CREATE POLICY
CREATE POLICY — define a new row level security policy for a table
Synopsis
CREATE POLICYname
ONtable_name
[ AS { PERMISSIVE | RESTRICTIVE } ] [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ] [ TO {role_name
| PUBLIC | CURRENT_USER | SESSION_USER } [, ...] ] [ USING (using_expression
) ] [ WITH CHECK (check_expression
) ]
Description
TheCREATE POLICY
command defines a new row-level security policy for a table. Note that row-level security must be enabled on the table (usingALTER TABLE ... ENABLE ROW LEVEL SECURITY
) in order for created policies to be applied.
A policy grants the permission to select, insert, update, or delete rows that match the relevant policy expression. Existing table rows are checked against the expression specified inUSING
, while new rows that would be created viaINSERT
orUPDATE
are checked against the expression specified inWITH CHECK
. When aUSING
expression returns true for a given row then that row is visible to the user, while if false or null is returned then the row is not visible. When aWITH CHECK
expression returns true for a row then that row is inserted or updated, while if false or null is returned then an error occurs.
ForINSERT
andUPDATE
statements,WITH CHECK
expressions are enforced afterBEFORE
triggers are fired, and before any actual data modifications are made. Thus aBEFORE ROW
trigger may modify the data to be inserted, affecting the result of the security policy check.WITH CHECK
expressions are enforced before any other constraints.
Policy names are per-table. Therefore, one policy name can be used for many different tables and have a definition for each table which is appropriate to that table.
Policies can be applied for specific commands or for specific roles. The default for newly created policies is that they apply for all commands and roles, unless otherwise specified. Multiple policies may apply to a single command; see below for more details.Table 242 summarizes how the different types of policy apply to specific commands.
For policies that can have bothUSING
andWITH CHECK
expressions (ALL
andUPDATE
), if noWITH CHECK
expression is defined, then theUSING
expression will be used both to determine which rows are visible (normalUSING
case) and which new rows will be allowed to be added (WITH CHECK
case).
If row-level security is enabled for a table, but no applicable policies exist, a“default deny” policy is assumed, so that no rows will be visible or updatable.
Parameters
name
The name of the policy to be created. This must be distinct from the name of any other policy for the table.
table_name
The name (optionally schema-qualified) of the table the policy applies to.
PERMISSIVE
Specify that the policy is to be created as a permissive policy. All permissive policies which are applicable to a given query will be combined together using the Boolean“OR” operator. By creating permissive policies, administrators can add to the set of records which can be accessed. Policies are permissive by default.
RESTRICTIVE
Specify that the policy is to be created as a restrictive policy. All restrictive policies which are applicable to a given query will be combined together using the Boolean“AND” operator. By creating restrictive policies, administrators can reduce the set of records which can be accessed as all restrictive policies must be passed for each record.
Note that there needs to be at least one permissive policy to grant access to records before restrictive policies can be usefully used to reduce that access. If only restrictive policies exist, then no records will be accessible. When a mix of permissive and restrictive policies are present, a record is only accessible if at least one of the permissive policies passes, in addition to all the restrictive policies.
command
The command to which the policy applies. Valid options are
ALL
,SELECT
,INSERT
,UPDATE
, andDELETE
.ALL
is the default. See below for specifics regarding how these are applied.role_name
The role(s) to which the policy is to be applied. The default is
PUBLIC
, which will apply the policy to all roles.using_expression
check_expression
AnySQL conditional expression (returning
boolean
). The conditional expression cannot contain any aggregate or window functions. This expression will be used inINSERT
andUPDATE
queries against the table if row level security is enabled. Only rows for which the expression evaluates to true will be allowed. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update. Note that thecheck_expression
is evaluated against the proposed new contents of the row, not the original contents.
Per-Command Policies
Table 242. Policies Applied by Command Type
Command | SELECT/ALL policy | INSERT/ALL policy | UPDATE/ALL policy | DELETE/ALL policy | |
---|---|---|---|---|---|
USING expression | WITH CHECK expression | USING expression | WITH CHECK expression | USING expression | |
SELECT | Existing row | — | — | — | — |
SELECT FOR UPDATE/SHARE | Existing row | — | Existing row | — | — |
INSERT | — | New row | — | — | — |
INSERT ... RETURNING | New row[a] | New row | — | — | — |
UPDATE | Existing & new rows[a] | — | Existing row | New row | — |
DELETE | Existing row[a] | — | — | — | Existing row |
ON CONFLICT DO UPDATE | Existing & new rows | — | Existing row | New row | — |
[a] If read access is required to the existing or new row (for example, a |
Application of Multiple Policies
expression
from RESTRICTIVE SELECT/ALL policy 1ANDexpression
from RESTRICTIVE SELECT/ALL policy 2AND...AND(expression
from PERMISSIVE SELECT/ALL policy 1 ORexpression
from PERMISSIVE SELECT/ALL policy 2 OR ...)ANDexpression
from RESTRICTIVE UPDATE/ALL policy 1ANDexpression
from RESTRICTIVE UPDATE/ALL policy 2AND...AND(expression
from PERMISSIVE UPDATE/ALL policy 1 ORexpression
from PERMISSIVE UPDATE/ALL policy 2 OR ...)
Notes
You must be the owner of a table to create or change policies for it.
Additional discussion and practical examples can be found inSection 5.7.
Compatibility
CREATE POLICY
is aPostgres Pro extension.