From 27190335787793546c286190621196e20f635bf8 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 23:14:55 +0000 Subject: [PATCH 1/2] =?UTF-8?q?docs(adr):=20ADR-0095=20D1=20note=20?= =?UTF-8?q?=E2=80=94=20Layer=200=20is=20inert=20on=2022=20of=20the=2023=20?= =?UTF-8?q?platform=20identity=20objects;=20Layer=201=20silence=20is=20to?= =?UTF-8?q?=20mean=20the=20object's=20declared=20default=20row=20scope?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR-0095 gains a dated 2026-10-18 note under D1 and a matching status-line entry for ruling E' (record 6250748677): Layer 0 is inert on 22 named objects that carry no organization_id column; sys_user_preference carries it, so Layer 0 bounds it to its organisation and its declared default is to apply inside that wall (measured by the tenancy census). On all 23, Layer 1 silence is to mean the object's declared default row scope, a protocol key on the object. ADR-0090 D12's 2026-10-17 note points to it: the boundary keeps its three conditions and gains no fourth. Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude --- ...permission-model-v2-concept-convergence.md | 5 ++++ ...-kernel-tenant-layer-and-posture-ladder.md | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/docs/adr/0090-permission-model-v2-concept-convergence.md b/docs/adr/0090-permission-model-v2-concept-convergence.md index 6cbb79b8fed..4cd0c84789e 100644 --- a/docs/adr/0090-permission-model-v2-concept-convergence.md +++ b/docs/adr/0090-permission-model-v2-concept-convergence.md @@ -600,6 +600,11 @@ not just "who did". > the walled `organization_admin` as tenant-level today; under this note it is organization-level. > No spec key is added, and the v18 upgrade entry's `replacement` text > (`18.walled-catalog-tenant-writes-retired`) stands as published: this note makes it true. +> +> The case held for #24164 is ruled (2026-10-18, ruling of record 6250748677, letter E′): an +> object is to carry its own default row scope, to apply when no held set carries a row policy for +> it ([ADR-0095](./0095-authz-kernel-tenant-layer-and-posture-ladder.md)'s 2026-10-18 note under +> D1), so #24136 keeps the three conditions above and gains no fourth. --- diff --git a/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md b/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md index 9aff54b2746..9f13adfa9af 100644 --- a/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md +++ b/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md @@ -1,6 +1,7 @@ # ADR-0095: Authorization Kernel Chain — Tenant Isolation as Layer 0, a Monotonic Posture Ladder, Capability-Derived Posture **Status**: Accepted (2026-07-14) — implemented: D1 tenant Layer 0 (`plugin-security/src/tenant-layer.ts`), D2/D3 posture ladder (`core/src/security/posture-ladder.ts`), locked by `authz-matrix-gate.test.ts` + `posture-ladder.test.ts` (#2920 B1–B4) +· **Amended** (2026-10-18, ruling of record 6250748677 on #24164, letter E′) — D1: Layer 0 is inert on 22 of the 23 platform objects that are to declare a default row scope, and walls the 23rd, `sys_user_preference`, to its organisation; on all 23, Layer 1 silence is to mean the object's declared default row scope, a protocol key (#24338), not no filter. See the note under D1. **Deciders**: ObjectStack Protocol Architects **Builds on**: [ADR-0002](./0002-environment-database-isolation.md) (environment-per-database), [ADR-0057](./0057-erp-authorization-core-business-units-and-scope-depth.md) (scope depth), [ADR-0066](./0066-unified-authorization-model.md) (unified authz model, superuser bypass), [ADR-0090](./0090-permission-model-v2-concept-convergence.md) (permission model v2), [ADR-0093](./0093-tenancy-mode-and-membership-lifecycle.md) (tenancy service) **Scopes**: the "cross-tenant RLS does not exist here" claim in [ADR-0073](./0073-automation-execution-identity.md) (see Context) @@ -174,6 +175,29 @@ the Layer 0 pre-image path. Adding a mandatory post-image tenant check would risk denying legitimate inserts before the auto-stamp runs — a regression, not a fix — so it is deliberately excluded from D1. +> **Amended 2026-10-18 (ruling of record 6250748677 on #24164, letter E′ — the +> maintainer's 「同意」) — Layer 1 silence on the platform identity objects.** +> Layer 0 is inert on 22 of the 23 objects the ruling names, which carry no +> `organization_id` column: the seven SCIM projections (`sys_scim_user`, +> `sys_scim_subject`, `sys_scim_projection_grant`, `sys_scim_identity_tombstone`, +> `sys_scim_group`, `sys_scim_group_member`, `sys_scim_connection_binding`), +> `sys_verification`, `sys_jwks`, `sys_organization`, `sys_user`, `sys_session`, +> `sys_account`, `sys_team_member`, `sys_two_factor`, `sys_api_key`, +> `sys_device_code`, `sys_oauth_access_token`, `sys_oauth_refresh_token`, +> `sys_oauth_consent`, `sys_oauth_application` and `sys_audit_log`. The 23rd, +> `sys_user_preference`, carries the organisation column, so Layer 0 bounds it to +> its organisation and its declared default is to apply inside that wall +> (measured: `scripts/platform-object-tenancy-census.json`, held to the tree by +> `scripts/check-platform-object-tenancy-census.mjs`). On all 23, Layer 1 +> silence (no held set carries a row policy for the object) is to mean the +> object's declared default row scope, not no filter. The default is a protocol +> key on the object (`ObjectSchema.defaultRowScope`, #24338); the platform +> objects are to declare it themselves (#24341), the one collection point is to +> apply it (#24340), and the registry is to refuse an `extend` contributor that +> sets or loosens it (#24341). Mainstream precedent: Salesforce OWD on the +> object; Dataverse ownership type on the table; PostgreSQL +> `CREATE POLICY ON table`. + ### D2 — A monotonic posture ladder, resolved once `resolveAuthzContext` resolves and carries an explicit posture: From 569c58e52e4784ff6a0b5229ede2af1f51978198 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 18 Oct 2026 23:19:02 +0000 Subject: [PATCH 2/2] docs(adr): the ADR-0095 D1 note names the card it lands as The note cites the ruling comment and all four cards of ruling E': the key, the collection point, the declarations, and this note. Claude-Session: https://claude.ai/code/session_019oFY6Hi35J7atvgVFnmoaK Co-authored-by: Claude --- docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md b/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md index 9f13adfa9af..f04fbc78e38 100644 --- a/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md +++ b/docs/adr/0095-authz-kernel-tenant-layer-and-posture-ladder.md @@ -175,8 +175,8 @@ the Layer 0 pre-image path. Adding a mandatory post-image tenant check would risk denying legitimate inserts before the auto-stamp runs — a regression, not a fix — so it is deliberately excluded from D1. -> **Amended 2026-10-18 (ruling of record 6250748677 on #24164, letter E′ — the -> maintainer's 「同意」) — Layer 1 silence on the platform identity objects.** +> **Amended 2026-10-18 (#24339; ruling of record 6250748677 on #24164, letter E′ +> — the maintainer's 「同意」) — Layer 1 silence on the platform identity objects.** > Layer 0 is inert on 22 of the 23 objects the ruling names, which carry no > `organization_id` column: the seven SCIM projections (`sys_scim_user`, > `sys_scim_subject`, `sys_scim_projection_grant`, `sys_scim_identity_tombstone`,