> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ALTER POLICY

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

The `ALTER POLICY` statement changes an existing <InternalLink path="row-level-security">row-level security (RLS)</InternalLink> policy on a table.

Allowed changes to a policy using `ALTER POLICY` include:

* Rename the policy.
* Change the applicable <InternalLink path="security-reference/authorization#roles">roles</InternalLink>.
* Modify the [`USING` expression](#parameters).
* Modify the [`WITH CHECK` expression](#parameters).

<Note>
  You cannot use `ALTER POLICY` to change the `PERMISSIVE`, `RESTRICTIVE`, or `FOR` clauses of a policy, as defined in `CREATE POLICY ... ON ... ( PERMISSIVE | RESTRICTIVE ) ... FOR ( ALL | SELECT | ... )`. To make these changes, drop the policy with <InternalLink path="drop-policy">`DROP POLICY`</InternalLink> and issue a new <InternalLink path="create-policy">`CREATE POLICY`</InternalLink> statement.
</Note>

## Syntax

```
ALTER POLICY policy_name ON table_name RENAME TO new_policy_name;

ALTER POLICY policy_name ON table_name
    [ TO ( role_name | PUBLIC | CURRENT_USER | SESSION_USER ) [, ...] ]
    [ USING ( using_expression ) ]
    [ WITH CHECK ( check_expression ) ];
```

## Parameters

| Parameter                         | Description                                                                                                                                                               |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `policy_name`                     | The identifier of the existing policy to be modified. Must be unique for the specified `table_name`.                                                                      |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ON table_name`                   | The name of the table on which the policy `policy_name` is defined.                                                                                                       |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `new_policy_name`                 | The new identifier for the policy. The `new_policy_name` must be a unique name on `table_name`.                                                                           |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| \`TO (role\_name                  | PUBLIC                                                                                                                                                                    | CURRENT\_USER | SESSION\_USER) \[, ...]\` | Specifies the database <InternalLink path="security-reference/authorization#roles">role(s)</InternalLink> to which the altered policy applies. These role(s) replace the existing set of roles for the policy. `PUBLIC` refers to all roles. `CURRENT_USER` and `SESSION_USER` refer to the current execution context's user (also available via <InternalLink path="functions-and-operators">functions</InternalLink> `current_user()` and `session_user()`). |
| `USING ( using_expression )`      | Replaces the previous value of this expression. For details about this expression, refer to <InternalLink path="create-policy#parameters">`CREATE POLICY`</InternalLink>. |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `WITH CHECK ( check_expression )` | Replaces the previous value of this expression. For details about this expression, refer to <InternalLink path="create-policy#parameters">`CREATE POLICY`</InternalLink>. |               |                           |                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

## Example

In this example, you will start by only allowing users to see or modify their own rows in an `orders` table. Then, as the schema is updated due to business requirements, you will refine the policy to take into account the new requirements.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE TABLE orders (user_id TEXT PRIMARY KEY, order_details TEXT);
```

The original policy on the table was as follows:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE POLICY user_orders_policy ON orders
    FOR ALL
    TO PUBLIC
    USING ( user_id = CURRENT_USER )
    WITH CHECK ( user_id = CURRENT_USER );
```

However, the `orders` table schema will be updated to include an `is_archived` flag, and the initial policy will need refinement.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
-- Assume this change was made after the initial policy was created
ALTER TABLE orders ADD COLUMN is_archived BOOLEAN DEFAULT FALSE NOT NULL;
CREATE INDEX idx_orders_user_id_is_archived ON orders(user_id, is_archived); -- For performance
```

The policy requirements have changed as follows:

1. The policy should now only apply to users belonging to the `customer_service` role, not `PUBLIC`.
2. Users in `customer_service` should only be able to view and modify orders that are **not** archived (`is_archived = FALSE`). Archived orders should be invisible/immutable via this policy.

This assumes the `customer_service` role has been created:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE ROLE customer_service;
```

This leads to the following `ALTER POLICY` statement:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER POLICY user_orders_policy ON orders
    TO customer_service
    USING ( user_id = CURRENT_USER AND is_archived = FALSE )
    WITH CHECK ( user_id = CURRENT_USER AND is_archived = FALSE );
```

The changes to the `ALTER POLICY` statement can be explained as follows:

* `TO customer_service`: Restricts the policy's application from all users (`PUBLIC`) to only those who are members of the `customer_service` role. Other users will no longer be affected by this specific policy (they would need other applicable policies or RLS would deny access by default).
* `USING ( user_id = CURRENT_USER AND is_archived = FALSE )`: Modifies the visibility rule. Now, `customer_service` users can only see rows that match their `user_id` *and* are not archived.
* `WITH CHECK ( user_id = CURRENT_USER AND is_archived = FALSE )`: Modifies the constraint for `INSERT`/`UPDATE`. Users attempting modifications must match the `user_id`, and the resulting row must not be archived. This prevents the user from inserting archived orders or updating an order to set `is_archived = TRUE` via operations governed by this policy.

The preceding `ALTER POLICY` statement represents a typical use case: it refines role targeting and adapts the policy logic to accommodate schema changes and evolving access control requirements.

## See also

* <InternalLink path="row-level-security">Row-level security (RLS) overview</InternalLink>
* <InternalLink path="create-policy">`CREATE POLICY`</InternalLink>
* <InternalLink path="drop-policy">`DROP POLICY`</InternalLink>
* <InternalLink path="show-policies">`SHOW POLICIES`</InternalLink>
* <InternalLink path="alter-table#enable-row-level-security">`ALTER TABLE ... ENABLE ROW LEVEL SECURITY`</InternalLink>
* <InternalLink path="alter-role#allow-a-role-to-bypass-row-level-security-rls">`ALTER ROLE ... WITH BYPASSRLS`</InternalLink>
* <InternalLink path="create-role#create-a-role-that-can-bypass-row-level-security-rls">`CREATE ROLE ... WITH BYPASSRLS`</InternalLink>
