summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml/man7/CREATE_POLICY.7
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/man7/CREATE_POLICY.7')
-rw-r--r--doc/src/sgml/man7/CREATE_POLICY.7655
1 files changed, 655 insertions, 0 deletions
diff --git a/doc/src/sgml/man7/CREATE_POLICY.7 b/doc/src/sgml/man7/CREATE_POLICY.7
new file mode 100644
index 0000000..af93bbf
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_POLICY.7
@@ -0,0 +1,655 @@
+'\" t
+.\" Title: CREATE POLICY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.5 Documentation
+.\" Source: PostgreSQL 15.5
+.\" Language: English
+.\"
+.TH "CREATE POLICY" "7" "2023" "PostgreSQL 15.5" "PostgreSQL 15.5 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_POLICY \- define a new row\-level security policy for a table
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE POLICY \fIname\fR ON \fItable_name\fR
+ [ AS { PERMISSIVE | RESTRICTIVE } ]
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { \fIrole_name\fR | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, \&.\&.\&.] ]
+ [ USING ( \fIusing_expression\fR ) ]
+ [ WITH CHECK ( \fIcheck_expression\fR ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBCREATE POLICY\fR
+command defines a new row\-level security policy for a table\&. Note that row\-level security must be enabled on the table (using
+\fBALTER TABLE \&.\&.\&. ENABLE ROW LEVEL SECURITY\fR) in order for created policies to be applied\&.
+.PP
+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 in
+USING, while new rows that would be created via
+INSERT
+or
+UPDATE
+are checked against the expression specified in
+WITH CHECK\&. When a
+USING
+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 a
+WITH 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\&.
+.PP
+For
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBMERGE\fR
+statements,
+WITH CHECK
+expressions are enforced after
+BEFORE
+triggers are fired, and before any actual data modifications are made\&. Thus a
+BEFORE 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\&.
+.PP
+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\&.
+.PP
+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\ \&287
+summarizes how the different types of policy apply to specific commands\&.
+.PP
+For policies that can have both
+USING
+and
+WITH CHECK
+expressions (ALL
+and
+UPDATE), if no
+WITH CHECK
+expression is defined, then the
+USING
+expression will be used both to determine which rows are visible (normal
+USING
+case) and which new rows will be allowed to be added (WITH CHECK
+case)\&.
+.PP
+If row\-level security is enabled for a table, but no applicable policies exist, a
+\(lqdefault deny\(rq
+policy is assumed, so that no rows will be visible or updatable\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the policy to be created\&. This must be distinct from the name of any other policy for the table\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table the policy applies to\&.
+.RE
+.PP
+PERMISSIVE
+.RS 4
+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
+\(lqOR\(rq
+operator\&. By creating permissive policies, administrators can add to the set of records which can be accessed\&. Policies are permissive by default\&.
+.RE
+.PP
+RESTRICTIVE
+.RS 4
+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
+\(lqAND\(rq
+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\&.
+.sp
+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\&.
+.RE
+.PP
+\fIcommand\fR
+.RS 4
+The command to which the policy applies\&. Valid options are
+\fBALL\fR,
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR\&.
+\fBALL\fR
+is the default\&. See below for specifics regarding how these are applied\&.
+.RE
+.PP
+\fIrole_name\fR
+.RS 4
+The role(s) to which the policy is to be applied\&. The default is
+PUBLIC, which will apply the policy to all roles\&.
+.RE
+.PP
+\fIusing_expression\fR
+.RS 4
+Any
+SQL
+conditional expression (returning
+boolean)\&. The conditional expression cannot contain any aggregate or window functions\&. This expression will be added to queries that refer to the table if row\-level security is enabled\&. Rows for which the expression returns true will be visible\&. Any rows for which the expression returns false or null will not be visible to the user (in a
+\fBSELECT\fR), and will not be available for modification (in an
+\fBUPDATE\fR
+or
+\fBDELETE\fR)\&. Such rows are silently suppressed; no error is reported\&.
+.RE
+.PP
+\fIcheck_expression\fR
+.RS 4
+Any
+SQL
+conditional expression (returning
+boolean)\&. The conditional expression cannot contain any aggregate or window functions\&. This expression will be used in
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+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 the
+\fIcheck_expression\fR
+is evaluated against the proposed new contents of the row, not the original contents\&.
+.RE
+.SS "Per\-Command Policies"
+.PP
+ALL
+.RS 4
+Using
+ALL
+for a policy means that it will apply to all commands, regardless of the type of command\&. If an
+ALL
+policy exists and more specific policies exist, then both the
+ALL
+policy and the more specific policy (or policies) will be applied\&. Additionally,
+ALL
+policies will be applied to both the selection side of a query and the modification side, using the
+USING
+expression for both cases if only a
+USING
+expression has been defined\&.
+.sp
+As an example, if an
+UPDATE
+is issued, then the
+ALL
+policy will be applicable both to what the
+UPDATE
+will be able to select as rows to be updated (applying the
+USING
+expression), and to the resulting updated rows, to check if they are permitted to be added to the table (applying the
+WITH CHECK
+expression, if defined, and the
+USING
+expression otherwise)\&. If an
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+command attempts to add rows to the table that do not pass the
+ALL
+policy\*(Aqs
+WITH CHECK
+expression, the entire command will be aborted\&.
+.RE
+.PP
+SELECT
+.RS 4
+Using
+SELECT
+for a policy means that it will apply to
+SELECT
+queries and whenever
+SELECT
+permissions are required on the relation the policy is defined for\&. The result is that only those records from the relation that pass the
+SELECT
+policy will be returned during a
+SELECT
+query, and that queries that require
+SELECT
+permissions, such as
+UPDATE, will also only see those records that are allowed by the
+SELECT
+policy\&. A
+SELECT
+policy cannot have a
+WITH CHECK
+expression, as it only applies in cases where records are being retrieved from the relation\&.
+.RE
+.PP
+INSERT
+.RS 4
+Using
+INSERT
+for a policy means that it will apply to
+INSERT
+commands and
+MERGE
+commands that contain
+INSERT
+actions\&. Rows being inserted that do not pass this policy will result in a policy violation error, and the entire
+INSERT
+command will be aborted\&. An
+INSERT
+policy cannot have a
+USING
+expression, as it only applies in cases where records are being added to the relation\&.
+.sp
+Note that
+INSERT
+with
+ON CONFLICT DO UPDATE
+checks
+INSERT
+policies\*(Aq
+WITH CHECK
+expressions only for rows appended to the relation by the
+INSERT
+path\&.
+.RE
+.PP
+UPDATE
+.RS 4
+Using
+UPDATE
+for a policy means that it will apply to
+UPDATE,
+SELECT FOR UPDATE
+and
+SELECT FOR SHARE
+commands, as well as auxiliary
+ON CONFLICT DO UPDATE
+clauses of
+INSERT
+commands\&.
+MERGE
+commands containing
+UPDATE
+actions are affected as well\&. Since
+UPDATE
+involves pulling an existing record and replacing it with a new modified record,
+UPDATE
+policies accept both a
+USING
+expression and a
+WITH CHECK
+expression\&. The
+USING
+expression determines which records the
+UPDATE
+command will see to operate against, while the
+WITH CHECK
+expression defines which modified rows are allowed to be stored back into the relation\&.
+.sp
+Any rows whose updated values do not pass the
+WITH CHECK
+expression will cause an error, and the entire command will be aborted\&. If only a
+USING
+clause is specified, then that clause will be used for both
+USING
+and
+WITH CHECK
+cases\&.
+.sp
+Typically an
+UPDATE
+command also needs to read data from columns in the relation being updated (e\&.g\&., in a
+WHERE
+clause or a
+RETURNING
+clause, or in an expression on the right hand side of the
+SET
+clause)\&. In this case,
+SELECT
+rights are also required on the relation being updated, and the appropriate
+SELECT
+or
+ALL
+policies will be applied in addition to the
+UPDATE
+policies\&. Thus the user must have access to the row(s) being updated through a
+SELECT
+or
+ALL
+policy in addition to being granted permission to update the row(s) via an
+UPDATE
+or
+ALL
+policy\&.
+.sp
+When an
+INSERT
+command has an auxiliary
+ON CONFLICT DO UPDATE
+clause, if the
+UPDATE
+path is taken, the row to be updated is first checked against the
+USING
+expressions of any
+UPDATE
+policies, and then the new updated row is checked against the
+WITH CHECK
+expressions\&. Note, however, that unlike a standalone
+UPDATE
+command, if the existing row does not pass the
+USING
+expressions, an error will be thrown (the
+UPDATE
+path will
+\fInever\fR
+be silently avoided)\&.
+.RE
+.PP
+DELETE
+.RS 4
+Using
+DELETE
+for a policy means that it will apply to
+DELETE
+commands\&. Only rows that pass this policy will be seen by a
+DELETE
+command\&. There can be rows that are visible through a
+SELECT
+that are not available for deletion, if they do not pass the
+USING
+expression for the
+DELETE
+policy\&.
+.sp
+In most cases a
+DELETE
+command also needs to read data from columns in the relation that it is deleting from (e\&.g\&., in a
+WHERE
+clause or a
+RETURNING
+clause)\&. In this case,
+SELECT
+rights are also required on the relation, and the appropriate
+SELECT
+or
+ALL
+policies will be applied in addition to the
+DELETE
+policies\&. Thus the user must have access to the row(s) being deleted through a
+SELECT
+or
+ALL
+policy in addition to being granted permission to delete the row(s) via a
+DELETE
+or
+ALL
+policy\&.
+.sp
+A
+DELETE
+policy cannot have a
+WITH CHECK
+expression, as it only applies in cases where records are being deleted from the relation, so that there is no new row to check\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.B Table\ \&287.\ \&Policies Applied by Command Type
+.TS
+allbox tab(:);
+lB lB lB lB s lB
+^ lB lB lB lB lB.
+T{
+Command
+T}:T{
+SELECT/ALL policy
+T}:T{
+INSERT/ALL policy
+T}:T{
+UPDATE/ALL policy
+T}:T{
+DELETE/ALL policy
+T}
+:T{
+USING expression
+T}:T{
+WITH CHECK expression
+T}:T{
+USING expression
+T}:T{
+WITH CHECK expression
+T}:T{
+USING expression
+T}
+.T&
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l s s s s s.
+T{
+\fBSELECT\fR
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBSELECT FOR UPDATE/SHARE\fR
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBINSERT\fR / \fBMERGE \&.\&.\&. THEN INSERT\fR
+T}:T{
+\(em
+T}:T{
+New row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBINSERT \&.\&.\&. RETURNING\fR
+T}:T{
+New row [a]
+T}:T{
+New row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBUPDATE\fR / \fBMERGE \&.\&.\&. THEN UPDATE\fR
+T}:T{
+Existing & new rows [a]
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+New row
+T}:T{
+\(em
+T}
+T{
+\fBDELETE\fR
+T}:T{
+Existing row [a]
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+Existing row
+T}
+T{
+\fBON CONFLICT DO UPDATE\fR
+T}:T{
+Existing & new rows
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+New row
+T}:T{
+\(em
+T}
+T{
+----
+.br
+[a]
+If read access is required to the existing or new row (for example, a
+WHERE
+or
+RETURNING
+clause that refers to columns from the relation)\&.
+T}
+.TE
+.sp 1
+.SS "Application of Multiple Policies"
+.PP
+When multiple policies of different command types apply to the same command (for example,
+SELECT
+and
+UPDATE
+policies applied to an
+UPDATE
+command), then the user must have both types of permissions (for example, permission to select rows from the relation as well as permission to update them)\&. Thus the expressions for one type of policy are combined with the expressions for the other type of policy using the
+AND
+operator\&.
+.PP
+When multiple policies of the same command type apply to the same command, then there must be at least one
+PERMISSIVE
+policy granting access to the relation, and all of the
+RESTRICTIVE
+policies must pass\&. Thus all the
+PERMISSIVE
+policy expressions are combined using
+OR, all the
+RESTRICTIVE
+policy expressions are combined using
+AND, and the results are combined using
+AND\&. If there are no
+PERMISSIVE
+policies, then access is denied\&.
+.PP
+Note that, for the purposes of combining multiple policies,
+ALL
+policies are treated as having the same type as whichever other type of policy is being applied\&.
+.PP
+For example, in an
+UPDATE
+command requiring both
+SELECT
+and
+UPDATE
+permissions, if there are multiple applicable policies of each type, they will be combined as follows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIexpression\fR from RESTRICTIVE SELECT/ALL policy 1
+AND
+\fIexpression\fR from RESTRICTIVE SELECT/ALL policy 2
+AND
+\&.\&.\&.
+AND
+(
+ \fIexpression\fR from PERMISSIVE SELECT/ALL policy 1
+ OR
+ \fIexpression\fR from PERMISSIVE SELECT/ALL policy 2
+ OR
+ \&.\&.\&.
+)
+AND
+\fIexpression\fR from RESTRICTIVE UPDATE/ALL policy 1
+AND
+\fIexpression\fR from RESTRICTIVE UPDATE/ALL policy 2
+AND
+\&.\&.\&.
+AND
+(
+ \fIexpression\fR from PERMISSIVE UPDATE/ALL policy 1
+ OR
+ \fIexpression\fR from PERMISSIVE UPDATE/ALL policy 2
+ OR
+ \&.\&.\&.
+)
+.fi
+.if n \{\
+.RE
+.\}
+.SH "NOTES"
+.PP
+You must be the owner of a table to create or change policies for it\&.
+.PP
+While policies will be applied for explicit queries against tables in the database, they are not applied when the system is performing internal referential integrity checks or validating constraints\&. This means there are indirect ways to determine that a given value exists\&. An example of this is attempting to insert a duplicate value into a column that is a primary key or has a unique constraint\&. If the insert fails then the user can infer that the value already exists\&. (This example assumes that the user is permitted by policy to insert records which they are not allowed to see\&.) Another example is where a user is allowed to insert into a table which references another, otherwise hidden table\&. Existence can be determined by the user inserting values into the referencing table, where success would indicate that the value exists in the referenced table\&. These issues can be addressed by carefully crafting policies to prevent users from being able to insert, delete, or update records at all which might possibly indicate a value they are not otherwise able to see, or by using generated values (e\&.g\&., surrogate keys) instead of keys with external meanings\&.
+.PP
+Generally, the system will enforce filter conditions imposed using security policies prior to qualifications that appear in user queries, in order to prevent inadvertent exposure of the protected data to user\-defined functions which might not be trustworthy\&. However, functions and operators marked by the system (or the system administrator) as
+LEAKPROOF
+may be evaluated before policy expressions, as they are assumed to be trustworthy\&.
+.PP
+Since policy expressions are added to the user\*(Aqs query directly, they will be run with the rights of the user running the overall query\&. Therefore, users who are using a given policy must be able to access any tables or functions referenced in the expression or they will simply receive a permission denied error when attempting to query the table that has row\-level security enabled\&. This does not change how views work, however\&. As with normal queries and views, permission checks and policies for the tables which are referenced by a view will use the view owner\*(Aqs rights and any policies which apply to the view owner, except if the view is defined using the
+security_invoker
+option (see
+\fBCREATE VIEW\fR)\&.
+.PP
+No separate policy exists for
+\fBMERGE\fR\&. Instead, the policies defined for
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR
+are applied while executing
+\fBMERGE\fR, depending on the actions that are performed\&.
+.PP
+Additional discussion and practical examples can be found in
+Section\ \&5.8\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE POLICY\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER POLICY (\fBALTER_POLICY\fR(7)), DROP POLICY (\fBDROP_POLICY\fR(7)), ALTER TABLE (\fBALTER_TABLE\fR(7))