Pre-existing docs imprecision, surfaced during PR #7792's review. Filed for a docs-only PR; no code is wrong here.
content/docs/permissions/authorization.mdx:55, the layer-5 row of the evaluation-order table, currently reads:
Row-level security | CEL predicates (using read filter, check write post-image) compiled into the query. If no applicable policy compiles, the result is a deny-all sentinel (fail-closed); …
The implementation's own contract is narrower. packages/plugins/plugin-security/src/security-plugin.ts:2591:
the RLS_DENY_FILTER sentinel → policies applied but none compiled, or resolution failed — fail-closed to zero rows.
So the sentinel fires when the applicable set is non-empty and every member fails to compile. An empty applicable set does not reach it at all — it yields no filter, which is why an object with no RLS policies is readable rather than invisible.
Why it is worth a line rather than shrugging off
It misled a reader in practice: the PM, reviewing #7792, read that sentence as documenting the fixed behaviour and instructed the dev to cite it as evidence that #7665 restored documented intent. The dev disputed it with the code and was right — the citation would have shipped a false claim in a security PR body. A sentence that can make a careful reader believe the write path was already fail-closed is worth two extra words.
Suggested wording, keeping the row's density:
If applicable policies exist but none of them compiles, the result is a deny-all sentinel (fail-closed); an object with no applicable policy is simply unfiltered at this layer.
Worth checking the same phrasing in the neighbouring pages while someone is in there (permissions-matrix.mdx's layer table, rls.mdx's fail-closed paragraph) — the compile-failure fail-closed rule is stated in more than one place and only this instance was checked.
Provenance
PR #7792 review (#7665). Deliberately not fixed in that PR: its dev was instructed not to doc-tidy beyond the one accuracy fix its own change required, and it correctly flagged this to the PM instead of either editing it or filing a duplicate. Filed unassigned and unqueued — recording, not claiming. ⛔ Not a rider on a code PR; if it is fixed, a dedicated docs-only PR is the route.
Pre-existing docs imprecision, surfaced during PR #7792's review. Filed for a docs-only PR; no code is wrong here.
content/docs/permissions/authorization.mdx:55, the layer-5 row of the evaluation-order table, currently reads:The implementation's own contract is narrower.
packages/plugins/plugin-security/src/security-plugin.ts:2591:So the sentinel fires when the applicable set is non-empty and every member fails to compile. An empty applicable set does not reach it at all — it yields no filter, which is why an object with no RLS policies is readable rather than invisible.
Why it is worth a line rather than shrugging off
It misled a reader in practice: the PM, reviewing #7792, read that sentence as documenting the fixed behaviour and instructed the dev to cite it as evidence that #7665 restored documented intent. The dev disputed it with the code and was right — the citation would have shipped a false claim in a security PR body. A sentence that can make a careful reader believe the write path was already fail-closed is worth two extra words.
Suggested wording, keeping the row's density:
Worth checking the same phrasing in the neighbouring pages while someone is in there (
permissions-matrix.mdx's layer table,rls.mdx's fail-closed paragraph) — the compile-failure fail-closed rule is stated in more than one place and only this instance was checked.Provenance
PR #7792 review (#7665). Deliberately not fixed in that PR: its dev was instructed not to doc-tidy beyond the one accuracy fix its own change required, and it correctly flagged this to the PM instead of either editing it or filing a duplicate. Filed unassigned and unqueued — recording, not claiming. ⛔ Not a rider on a code PR; if it is fixed, a dedicated docs-only PR is the route.