Commit b54aaab
fix(plugin-security): require by-id write targets to be within the caller's readable set under select-only RLS (#7792)
* fix(plugin-security): require by-id write targets to be within the caller's readable set under select-only RLS
An object whose row narrowing is authored as `operation: 'select'` rules only
had an open by-id write path. A contributor could PATCH records they could not
read — 200, values persisted — on the master object AND on a
`controlled_by_parent` detail, while the read side correctly hid the same rows
(GET 404, absent from list). Measured live on the stock showcase by QA run
#7637, on three objects, twice each.
The by-id write pre-image gate, the controlled_by_parent master check and the
bulk write filter all compose the RLS filter for the WRITE operation. With no
update-scope policy applicable to the caller that filter compiled to a null
Layer 1, and all three row gates became a no-op at once; OWD
`public_read_write` then let `resolveSharingCanEdit` admit the write, and the
detail derived its access from that same permissive master verdict.
An empty write-class policy collection now derives its scope from the caller's
SELECT narrowing, at the single decision site in `computeLayeredRlsFilter` —
the same policies, compiled by the same compiler, that the read path enforces.
Deliberately not derived: when any write-class policy applies (an authored
predicate or the in-domain platform ownership floor), so app-authored write
wideners keep deciding alone and the #7401 / #6736 directions are preserved
exactly; for `insert`, which has no pre-image to be visible; and when the
caller holds the read-side superuser bypass on a posture-permitting object,
whose readable set is unbounded — the mirror of the read path's own Layer 1
short-circuit, so a derived write scope can never be narrower than the read
scope it comes from.
Fixes #7665
Co-Authored-By: Claude <noreply@anthropic.com>
* docs(permissions): record that a `select` policy also bounds writes when no write-class policy applies
The "Choosing `operation`" paragraph described `select` as narrowing reads and
the write classes as guarding "the matching write" — the exact mental model
that produced #7665, and now an understatement of what the platform enforces.
States the derivation and its three boundaries: it applies only when no
write-class policy applies to the caller (an authored write predicate keeps
deciding its class alone), never for `insert`, and never for a caller holding
the read-side superuser bypass. Adds a pointer from the `operation` property
row.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 098f4bb commit b54aaab
6 files changed
Lines changed: 832 additions & 25 deletions
File tree
- .changeset
- content/docs/permissions
- packages
- plugins/plugin-security/src
- qa/dogfood/test
- fixtures
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
61 | | - | |
| 61 | + | |
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
74 | 85 | | |
75 | 86 | | |
76 | 87 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1426 | 1426 | | |
1427 | 1427 | | |
1428 | 1428 | | |
1429 | | - | |
1430 | | - | |
1431 | | - | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
1432 | 1436 | | |
1433 | 1437 | | |
1434 | 1438 | | |
| |||
1586 | 1590 | | |
1587 | 1591 | | |
1588 | 1592 | | |
1589 | | - | |
1590 | | - | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
1591 | 1599 | | |
1592 | 1600 | | |
1593 | 1601 | | |
| |||
3925 | 3933 | | |
3926 | 3934 | | |
3927 | 3935 | | |
3928 | | - | |
| 3936 | + | |
| 3937 | + | |
| 3938 | + | |
| 3939 | + | |
| 3940 | + | |
| 3941 | + | |
| 3942 | + | |
| 3943 | + | |
| 3944 | + | |
| 3945 | + | |
| 3946 | + | |
| 3947 | + | |
| 3948 | + | |
| 3949 | + | |
| 3950 | + | |
| 3951 | + | |
| 3952 | + | |
| 3953 | + | |
| 3954 | + | |
| 3955 | + | |
| 3956 | + | |
| 3957 | + | |
| 3958 | + | |
| 3959 | + | |
| 3960 | + | |
| 3961 | + | |
| 3962 | + | |
| 3963 | + | |
| 3964 | + | |
| 3965 | + | |
| 3966 | + | |
| 3967 | + | |
| 3968 | + | |
| 3969 | + | |
| 3970 | + | |
| 3971 | + | |
| 3972 | + | |
| 3973 | + | |
| 3974 | + | |
| 3975 | + | |
| 3976 | + | |
| 3977 | + | |
| 3978 | + | |
| 3979 | + | |
| 3980 | + | |
| 3981 | + | |
| 3982 | + | |
| 3983 | + | |
3929 | 3984 | | |
3930 | 3985 | | |
3931 | 3986 | | |
| |||
0 commit comments