Filed by the domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357) from the at-tier review of PR #19946 (record 5807410719, ③, "Not carried at all"). ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim.
The runtime
packages/plugins/plugin-security/src/security-plugin.ts:3007-3014 (the seat read it on origin/main aeaaa44292). For an update, the post-image check runs only when extractSingleId(opCtx) finds one id. A bulk update takes the branch that logs [Security] RLS check on bulk update '<object>' is not post-image validated (governed by the using-scoped where); single-id writes are checked. and sets the post-image to null. The code comment gives the reason: "A bulk update (no single id) cannot form a post-image here — it is governed by the using-based AST scoping (step 3); we log and skip rather than guess."
The gap
That reasoning assumes the policy has a using. RowLevelSecurityPolicySchema accepts a policy that declares only check. For such a policy nothing scopes a bulk update's where, and nothing checks its post-image.
Measured by the #19946 round-2 reviewer on driver-sql through the real SecurityPlugin + ObjectQL, at ba90ddb578: under a check-only policy, update(…, { where, multi: true }) as the caller was admitted and stored (b1: open → closed), a transition the check was written to refuse.
Why it matters
A check is the write-side guarantee of a row-level policy. Today the guarantee holds for inserts and single-id updates, but a bulk update by where escapes it whenever the policy has no using. Related, not duplicates:
Seam: spec:RowLevelSecurityPolicySchema.check → runtime: plugin-security update post-image check (extractSingleId == null branch).
Dedupe words: bulk update check not validated · multi true update rls check skipped · check-only policy bulk write admitted · governed by the using-scoped where
Filed by the
domain:specseat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357) from the at-tier review of PR #19946 (record5807410719, ③, "Not carried at all"). ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim.The runtime
packages/plugins/plugin-security/src/security-plugin.ts:3007-3014(the seat read it onorigin/mainaeaaa44292). For an update, the post-imagecheckruns only whenextractSingleId(opCtx)finds one id. A bulk update takes the branch that logs[Security] RLS check on bulk update '<object>' is not post-image validated (governed by the using-scoped where); single-id writes are checked.and sets the post-image tonull. The code comment gives the reason: "A bulk update (no single id) cannot form a post-image here — it is governed by the using-based AST scoping (step 3); we log and skip rather than guess."The gap
That reasoning assumes the policy has a
using.RowLevelSecurityPolicySchemaaccepts a policy that declares onlycheck. For such a policy nothing scopes a bulk update'swhere, and nothing checks its post-image.Measured by the #19946 round-2 reviewer on driver-sql through the real
SecurityPlugin+ObjectQL, atba90ddb578: under acheck-only policy,update(…, { where, multi: true })as the caller was admitted and stored (b1: open → closed), a transition thecheckwas written to refuse.Why it matters
A
checkis the write-side guarantee of a row-level policy. Today the guarantee holds for inserts and single-id updates, but a bulk update bywhereescapes it whenever the policy has nousing. Related, not duplicates:updatepolicy suppresses the #7665 write-scope derivation — a contributor by-id-writes showcase_invoice rows it cannot read #8059 (closed) fixed the by-id path for acheck-onlyupdatepolicy;RowLevelSecurityPolicySchema.checkis published as "defaults to USING clause if not specified", but the write check runs only policies that declarecheck, so a USING-only policy never gates an INSERT #19942 is the opposite case: ausing-only policy never gates an insert.Seam:
spec:RowLevelSecurityPolicySchema.check→ runtime:plugin-securityupdate post-image check (extractSingleId== null branch).Dedupe words:
bulk update check not validated·multi true update rls check skipped·check-only policy bulk write admitted·governed by the using-scoped where