---
title: "CREATE POLICY"
url: "https://docs.yugabyte.com/stable/api/ysql/the-sql-language/statements/dcl_create_policy/"
---

# CREATE POLICY

Use the CREATE POLICY statement to create a row level security policy for a table to select, insert, update, or delete rows that match the relevant policy expression.

## Synopsis

Use the CREATE POLICY statement to create a row-level security policy for a table.

A policy grants the permission to select, insert, update, or delete rows that match the relevant policy expression.

Row level security must be enabled on the table using [ALTER TABLE](/stable/api/ysql/the-sql-language/statements/ddl_alter_table "ALTER TABLE") for the policies to take effect.

## Syntax

- [![Grammar Icon](/icons/file-lines.svg)Grammar](#grammar-1)
- [![Diagram Icon](/icons/diagram.svg)Diagram](#diagram-1)

```output.ebnf
create_policy ::= CREATE POLICY name ON table_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 ) ]
```

#### create\_policy

CREATEPOLICY[name](/stable/api/ysql/syntax_resources/grammar_diagrams#name)ON[table\_name](/stable/api/ysql/syntax_resources/grammar_diagrams#table-name)ASPERMISSIVERESTRICTIVEFORALLSELECTINSERTUPDATEDELETETO,[role\_name](/stable/api/ysql/syntax_resources/grammar_diagrams#role-name)PUBLICCURRENT\_USERSESSION\_USERUSING([using\_expression](/stable/api/ysql/syntax_resources/grammar_diagrams#using-expression))WITHCHECK([check\_expression](/stable/api/ysql/syntax_resources/grammar_diagrams#check-expression))

Where

- `name` is the name of the new policy. This must be distinct from any other policy name for that table.
- `table_name` is the name of the table that the policy applies to.
- PERMISSIVE / RESTRICTIVE specifies that the policy is permissive or restrictive. While applying policies to a table, permissive policies are combined together using a logical OR operator, while restrictive policies are combined using logical AND operator. Restrictive policies are used to reduce the number of records that can be accessed. Default is permissive.
- `role_name` is the role(s) to which the policy is applied. Default is PUBLIC which applies the policy to all roles.
- `using_expression` is a SQL conditional expression. Only rows for which the condition returns to true will be visible in a SELECT and available for modification in an UPDATE or DELETE.
- `check_expression` is a SQL conditional expression that is used only for INSERT and UPDATE queries. Only rows for which the expression evaluates to true will be allowed in an INSERT or UPDATE. Note that unlike `using_expression`, this is evaluated against the proposed new contents of the row.

## Examples

- Create a permissive policy.
  
  ```plpgsql
  yugabyte=# CREATE POLICY p1 ON document
    USING (dlevel <= (SELECT level FROM user_account WHERE ybuser = current_user));
  ```
- Create a restrictive policy.
  
  ```plpgsql
  yugabyte=# CREATE POLICY p_restrictive ON document AS RESTRICTIVE TO user_bob
      USING (cid <> 44);
  ```
- Create a policy with a CHECK condition for inserts.
  
  ```plpgsql
  yugabyte=# CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user);
  ```

## See also

- [ALTER POLICY](/stable/api/ysql/the-sql-language/statements/dcl_alter_policy "ALTER POLICY")
- [DROP POLICY](/stable/api/ysql/the-sql-language/statements/dcl_drop_policy "DROP POLICY")
- [ALTER TABLE](/stable/api/ysql/the-sql-language/statements/ddl_alter_table "ALTER TABLE")
