Skip to content

Commit 8f3b6b4

Browse files
committed
Update with spilchen feedback (3)
1 parent faa5864 commit 8f3b6b4

File tree

3 files changed

+15
-17
lines changed

3 files changed

+15
-17
lines changed

src/current/v25.2/alter-table.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Subcommand | Description | Can combine with other subcommands?
6060
[`RENAME TO`](#rename-to) | Change the names of tables. | No
6161
[`RESET {storage parameter}`](#reset-storage-parameter) | Reset a storage parameter on a table to its default value. | Yes
6262
[`(ENABLE, DISABLE) ROW LEVEL SECURITY`](#enable-disable-row-level-security) | Enable or disable [row-level security]({% link {{ page.version.version }}/row-level-security.md %}) for a table. | Yes
63-
[`(FORCE, NO FORCE) ROW LEVEL SECURITY`](#force-unforce-row-level-security) | Force the table owner to be subject to [row-level security]({% link {{ page.version.version }}/row-level-security.md %}) policies defined on a table. | No
63+
[`(FORCE, NO FORCE) ROW LEVEL SECURITY`](#force-row-level-security) | Force the table owner to be subject to [row-level security]({% link {{ page.version.version }}/row-level-security.md %}) policies defined on a table. | Yes
6464
[`SET {storage parameter}`](#set-storage-parameter) | Set a storage parameter on a table. | Yes
6565
[`SET LOCALITY`](#set-locality) | Set the table locality for a table in a [multi-region database]({% link {{ page.version.version }}/multiregion-overview.md %}). | No
6666
[`SET SCHEMA`](#set-schema) | Change the [schema]({% link {{ page.version.version }}/sql-name-resolution.md %}) of a table. | No
@@ -477,7 +477,7 @@ For usage, see [Synopsis](#synopsis).
477477
For examples, see [Enable and disable row-level security](#enable-and-disable-row-level-security).
478478

479479
{{site.data.alerts.callout_info}}
480-
RLS applies to a table **only when explicitly enabled** using `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`. Roles exempt from RLS policies include [admins]({% link {{ page.version.version }}/security-reference/authorization.md %}#roles), [table owners]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership) (unless the table is set to [`FORCE ROW LEVEL SECURITY`](#force-and-unforce-row-level-security)), and [roles with `BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls).
480+
RLS applies to a table **only when explicitly enabled** using `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`. Roles exempt from RLS policies include [admins]({% link {{ page.version.version }}/security-reference/authorization.md %}#roles), [table owners]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership) (unless the table is set to [`FORCE ROW LEVEL SECURITY`](#force-row-level-security)), and [roles with `BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls).
481481
{{site.data.alerts.end}}
482482

483483
#### Required privileges
@@ -497,7 +497,7 @@ The user must be a member of the [`admin`]({% link {{ page.version.version }}/se
497497

498498
Use this statement when you need to ensure that all access, including by the table owner, adheres to the defined RLS policies. For example, in production or multi-tenant environments where all roles (including administrators) must operate under policy constraints. Note that this statement only has an affect if [`ALTER TABLE ... ENABLE ROW LEVEL SECURITY`](#enable-disable-row-level-security) is also set.
499499

500-
For examples, see [Force and unforce row-level security](#force-and-unforce-row-level-security).
500+
For examples, see [Force row-level security](#force-row-level-security).
501501

502502
{{site.data.alerts.callout_danger}}
503503
Users with the `BYPASSRLS` [role option]({% link {{ page.version.version }}/security-reference/authorization.md %}#role-options) can still bypass RLS even when `ALTER TABLE ... FORCE ROW LEVEL SECURITY` is enabled.
@@ -3095,10 +3095,10 @@ ALTER TABLE orders DISABLE ROW LEVEL SECURITY;
30953095
~~~
30963096
30973097
{{site.data.alerts.callout_info}}
3098-
RLS applies to a table **only when explicitly enabled** using `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`. Roles exempt from RLS policies include [admins]({% link {{ page.version.version }}/security-reference/authorization.md %}#roles), [table owners]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership) (unless the table is set to [`FORCE ROW LEVEL SECURITY`](#force-and-unforce-row-level-security)), and [roles with `BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls).
3098+
RLS applies to a table **only when explicitly enabled** using `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`. Roles exempt from RLS policies include [admins]({% link {{ page.version.version }}/security-reference/authorization.md %}#roles), [table owners]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership) (unless the table is set to [`FORCE ROW LEVEL SECURITY`](#force-row-level-security)), and [roles with `BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls).
30993099
{{site.data.alerts.end}}
31003100
3101-
### Force and unforce row-level security
3101+
### Force row-level security
31023102
31033103
To ensure that all access, including by the table [owner]({% link {{ page.version.version }}/security-reference/authorization.md %}#object-ownership), adheres to the defined [row-level security]({% link {{ page.version.version }}/row-level-security.md %}) policies, issue the following statement:
31043104

src/current/v25.2/create-policy.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ CREATE POLICY [ IF NOT EXISTS ] policy_name ON table_name
3434

3535
Parameter | Description
3636
----------|------------
37-
`IF NOT EXISTS` | Used to specify that the policy will only be created if one with the same `policy_name` does not already exist on `table_name`.
37+
`IF NOT EXISTS` | Used to specify that the policy will only be created if one with the same `policy_name` does not already exist on `table_name`. If a policy with that name does already exist, the statement will not return an error if this parameter is used.
3838
`policy_name` | Unique identifier for the policy on the table.
3939
`table_name` | The [table]({% link {{ page.version.version }}/schema-design-table.md %}) to which the policy applies.
4040
`AS { PERMISSIVE, RESTRICTIVE }` | (**Default**: `PERMISSIVE`.) For `PERMISSIVE`, policies are combined using `OR`. A row is accessible if *any* permissive policy grants access. For `RESTRICTIVE`, policies are combined using `AND`. The overall policy enforcement is determined by evaluating a logical expression of the form: `(permissive policies) AND (restrictive policies)`. This means that all restrictive policies must grant access for a row to be accessible, and restrictive policies are evaluated *after* permissive policies. This means that you need to have at least one `PERMISSIVE` policy in place before applying `RESTRICTIVE` policies. If any restrictive policy denies access, the row is inaccessible, regardless of the permissive policies.
@@ -56,18 +56,16 @@ The following table shows which policies are applied to which statement types, w
5656
| `SELECT` ||||||
5757
| `SELECT ... FOR UPDATE / FOR SHARE` ||||||
5858
| `INSERT` ||||||
59-
| `INSERT ... RETURNING` | |||||
60-
| `UPDATE` | |||||
61-
| `DELETE` | |||||
59+
| `INSERT ... RETURNING` | |||||
60+
| `UPDATE` | |||||
61+
| `DELETE` | |||||
6262
| `INSERT ... ON CONFLICT DO UPDATE` ||||||
6363
| `UPSERT` ||||||
6464

65-
‡ The `SELECT` check is only evaluated when the statement actually needs to read from the relation, e.g., in a `WHERE`, `SET`, or `RETURNING` clause that references table columns.
66-
6765
Additional considerations include:
6866

6967
- `SELECT` evaluation: CockroachDB always evaluates `SELECT` (`USING`) policies for `INSERT`, `UPDATE`, and `DELETE`, even when the statement doesn't reference table columns.
70-
- `ON CONFLICT ... DO NOTHING`: CockroachDB still runs constraint and row-level policy checks on the `VALUES` clause even when the candidate row is discarded because of a conflict. This is a known limitation described in [cockroachdb/cockroach#35370](https://github.com/cockroachdb/cockroach/issues/35370).
68+
- `ON CONFLICT ... DO NOTHING`: CockroachDB does not run the constraint and row-level policy checks on the `VALUES` clause if the candidate row has a conflict. This is a known limitation described in [cockroachdb/cockroach#35370](https://github.com/cockroachdb/cockroach/issues/35370).
7169

7270
## Examples
7371

@@ -98,7 +96,7 @@ CREATE POLICY user_orders_policy ON orders
9896
- [`DROP POLICY`]({% link {{ page.version.version }}/drop-policy.md %})
9997
- [`SHOW POLICIES`]({% link {{ page.version.version }}/show-policies.md %})
10098
- [`ALTER TABLE {ENABLE, DISABLE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#enable-disable-row-level-security)
101-
- [`ALTER TABLE {FORCE, NO FORCE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-unforce-row-level-security)
99+
- [`ALTER TABLE {FORCE, NO FORCE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-row-level-security)
102100
- [`ALTER ROLE ... WITH BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls)
103101
- [`CREATE ROLE ... WITH BYPASSRLS`]({% link {{ page.version.version }}/create-role.md %}#create-a-role-that-can-bypass-row-level-security-rls)
104102

src/current/v25.2/row-level-security.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ For an example, see [`DROP POLICY`]({% link {{ page.version.version }}/drop-poli
126126
For examples, see:
127127

128128
- [`ALTER TABLE ... (ENABLE, DISABLE) ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#enable-disable-row-level-security).
129-
- [`ALTER TABLE ... (FORCE, NO FORCE) ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-unforce-row-level-security).
129+
- [`ALTER TABLE ... (FORCE, NO FORCE) ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-row-level-security).
130130

131131
### RLS for Data Security (Fine-Grained Access Control)
132132

@@ -188,7 +188,7 @@ GRANT SELECT ON employees TO employee;
188188

189189
#### Enable row-level security for fine-grained access control
190190

191-
Next, enable row-level security using the [`ALTER TABLE ... ENABLE ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#enable-disable-row-level-security) statement. Optionally, you may want to ensure that the table owner is also subject to RLS using [`ALTER TABLE ... FORCE ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-unforce-row-level-security).
191+
Next, enable row-level security using the [`ALTER TABLE ... ENABLE ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#enable-disable-row-level-security) statement. Optionally, you may want to ensure that the table owner is also subject to RLS using [`ALTER TABLE ... FORCE ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-row-level-security).
192192

193193
{% include_cached copy-clipboard.html %}
194194
~~~ sql
@@ -456,7 +456,7 @@ CREATE POLICY tenant_isolation ON invoices
456456
Explanation of policy:
457457

458458
- `AS PERMISSIVE`: Necessary because you need at least one permissive policy. The permissive policy above has logic to show results for a default tenant ID if the `application_name` is omitted or improperly formatted.
459-
- `AS RESTRICTIVE`: Makes the policy mandatory. If other policies exist, they must *also* pass. For simple tenant isolation, this is often the safest default.
459+
- `AS RESTRICTIVE`: Makes the policy mandatory. If other policies exist, they must *also* pass. For simple tenant isolation, this is often the safest default. The restrictive policy above applies to the `app_dev` role, so that anyone assigned to the `app_dev` role must use the correctly formatted `application_name`, and is not allowed to fallback to the default tenant ID.
460460
- `FOR ALL`: Covers all data modification and retrieval.
461461
- `TO PUBLIC`: Applies the policy broadly. Roles should primarily manage table-level access using `GRANT`, while this policy handles row-level visibility.
462462
- `USING`: Ensures queries only see rows matching the session's tenant ID, which is passed in using the `application_name` session variable and extracted using the `split_part` function.
@@ -533,7 +533,7 @@ For a demo showing how to combine Row-level security with [Multi-region SQL]({%
533533
- [`ALTER POLICY`]({% link {{ page.version.version }}/alter-policy.md %})
534534
- [`DROP POLICY`]({% link {{ page.version.version }}/drop-policy.md %})
535535
- [`ALTER TABLE {ENABLE, DISABLE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#enable-disable-row-level-security)
536-
- [`ALTER TABLE {FORCE, NO FORCE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-unforce-row-level-security)
536+
- [`ALTER TABLE {FORCE, NO FORCE} ROW LEVEL SECURITY`]({% link {{ page.version.version }}/alter-table.md %}#force-row-level-security)
537537
- [`CREATE ROLE ... WITH BYPASSRLS`]({% link {{ page.version.version }}/create-role.md %}#create-a-role-that-can-bypass-row-level-security-rls)
538538
- [`ALTER ROLE ... WITH BYPASSRLS`]({% link {{ page.version.version }}/alter-role.md %}#allow-a-role-to-bypass-row-level-security-rls)
539539

0 commit comments

Comments
 (0)