@@ -2919,4 +2919,175 @@ DROP ROLE test_role1;
29192919statement ok
29202920DROP ROLE test_role2;
29212921
2922+ # Ensure that if a role has the BYPASSRLS option or privilege set, that it's
2923+ # exempt from policies.
2924+ subtest bypassrls
2925+
2926+ statement ok
2927+ CREATE TABLE bypassrls (id INT PRIMARY KEY, val TEXT);
2928+
2929+ statement ok
2930+ CREATE USER bypassrls_user;
2931+
2932+ statement ok
2933+ GRANT ALL ON bypassrls TO bypassrls_user;
2934+
2935+ statement ok
2936+ ALTER TABLE bypassrls ENABLE ROW LEVEL SECURITY;
2937+
2938+ statement ok
2939+ CREATE POLICY pol1 ON bypassrls TO bypassrls_user USING (val like 'visible: %');
2940+
2941+ statement ok
2942+ CREATE FUNCTION insert_policy_violation_as_session_user(id INT) RETURNS TABLE(id INT, description TEXT)
2943+ LANGUAGE SQL AS
2944+ $$
2945+ INSERT INTO bypassrls VALUES (id, 'hidden: value') RETURNING id, val
2946+ $$;
2947+
2948+ # This function is like the above, except it will always be run as admin since
2949+ # it uses SECURITY DEFINER.
2950+ statement ok
2951+ CREATE FUNCTION insert_policy_violation_as_admin(id INT) RETURNS TABLE(id INT, description TEXT)
2952+ LANGUAGE SQL AS
2953+ $$
2954+ INSERT INTO bypassrls VALUES (id, 'hidden: value') RETURNING id, val
2955+ $$ SECURITY DEFINER;
2956+
2957+ statement ok
2958+ INSERT INTO bypassrls VALUES (0, 'visible: 0'), (1, 'hidden: 1'), (2, 'visible: 2');
2959+
2960+ query IT
2961+ SELECT * FROM insert_policy_violation_as_admin(10);
2962+ ----
2963+ 10 hidden: value
2964+
2965+ query IT
2966+ SELECT * FROM insert_policy_violation_as_session_user(11);
2967+ ----
2968+ 11 hidden: value
2969+
2970+ query IT
2971+ SELECT * FROM bypassrls ORDER BY id;
2972+ ----
2973+ 0 visible: 0
2974+ 1 hidden: 1
2975+ 2 visible: 2
2976+ 10 hidden: value
2977+ 11 hidden: value
2978+
2979+ statement ok
2980+ SET ROLE bypassrls_user;
2981+
2982+ query IT
2983+ SELECT * FROM bypassrls ORDER BY id;
2984+ ----
2985+ 0 visible: 0
2986+ 2 visible: 2
2987+
2988+ query IT
2989+ SELECT * FROM insert_policy_violation_as_admin(20);
2990+ ----
2991+ 20 hidden: value
2992+
2993+ statement error pq: new row violates row-level security policy for table "bypassrls"
2994+ SELECT * FROM insert_policy_violation_as_session_user(21);
2995+
2996+ statement ok
2997+ SET ROLE root;
2998+
2999+ statement error pq: conflicting role options
3000+ ALTER ROLE bypassrls_user BYPASSRLS NOBYPASSRLS;
3001+
3002+ statement ok
3003+ ALTER ROLE bypassrls_user BYPASSRLS;
3004+
3005+ statement ok
3006+ SET ROLE bypassrls_user;
3007+
3008+ query IT
3009+ SELECT * FROM bypassrls ORDER BY id;
3010+ ----
3011+ 0 visible: 0
3012+ 1 hidden: 1
3013+ 2 visible: 2
3014+ 10 hidden: value
3015+ 11 hidden: value
3016+ 20 hidden: value
3017+
3018+ query IT
3019+ SELECT * FROM insert_policy_violation_as_admin(30);
3020+ ----
3021+ 30 hidden: value
3022+
3023+ query IT
3024+ SELECT * FROM insert_policy_violation_as_session_user(31);
3025+ ----
3026+ 31 hidden: value
3027+
3028+ statement ok
3029+ SET ROLE root
3030+
3031+ statement ok
3032+ ALTER ROLE bypassrls_user NOBYPASSRLS;
3033+
3034+ statement ok
3035+ GRANT SYSTEM BYPASSRLS TO bypassrls_user;
3036+
3037+ query TTB colnames
3038+ SELECT * FROM [SHOW SYSTEM GRANTS] WHERE privilege_type = 'BYPASSRLS';
3039+ ----
3040+ grantee privilege_type is_grantable
3041+ bypassrls_user BYPASSRLS false
3042+
3043+ statement ok
3044+ SET ROLE bypassrls_user;
3045+
3046+ query IT
3047+ SELECT * FROM bypassrls ORDER BY id;
3048+ ----
3049+ 0 visible: 0
3050+ 1 hidden: 1
3051+ 2 visible: 2
3052+ 10 hidden: value
3053+ 11 hidden: value
3054+ 20 hidden: value
3055+ 30 hidden: value
3056+ 31 hidden: value
3057+
3058+ query IT
3059+ SELECT * FROM insert_policy_violation_as_session_user(40);
3060+ ----
3061+ 40 hidden: value
3062+
3063+ statement ok
3064+ SET ROLE root;
3065+
3066+ statement ok
3067+ REVOKE SYSTEM BYPASSRLS FROM bypassrls_user;
3068+
3069+ statement ok
3070+ SET ROLE bypassrls_user;
3071+
3072+ query IT
3073+ SELECT * FROM bypassrls ORDER BY id;
3074+ ----
3075+ 0 visible: 0
3076+ 2 visible: 2
3077+
3078+ statement error pq: new row violates row-level security policy for table "bypassrls"
3079+ SELECT * FROM insert_policy_violation_as_session_user(50);
3080+
3081+ statement ok
3082+ SET ROLE root;
3083+
3084+ statement ok
3085+ DROP FUNCTION insert_policy_violation_as_admin, insert_policy_violation_as_session_user
3086+
3087+ statement ok
3088+ DROP TABLE bypassrls;
3089+
3090+ statement ok
3091+ DROP USER bypassrls_user;
3092+
29223093subtest end
0 commit comments