You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e9bb178
Browse filesBrowse the repository at this point in the historyBrowse files
docs(adr): record the EXTERNAL rung's channel list (ruling 6355206139, letter B)
The Tier H text for #25233. ADR-0095 D2 and D3, ADR-0099's EXTERNAL
column, D3 and I7, and ADR-0090 D11 now say what #25541 enforces: an
external is a member who holds the `external` organization role, and it
reaches rows through shares and share links, sharing rules, and the
grants it holds with their RLS, never the OWD baseline. ADR-0090 D11's
external-audience matrix column is retired, and ADR-0135 gains a dated
note on the third population. The core floor's docblock stops listing
controlled_by_parent among the models it closes.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AZbN6PU5Xz4WTi6NKmyKhN
docs: the external org-wide-default floor's docblock no longer lists `controlled_by_parent` among the models it closes
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
`owdForAudience`'s module docblock said an external is floored on a `controlled_by_parent` detail. It is not: plugin-sharing exempts the detail, whose rows follow its master, and the master meets the floor (#25541). Comment only; no behaviour changes.
Copy file name to clipboardExpand all lines: docs/adr/0090-permission-model-v2-concept-convergence.md
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,7 @@
4
4
· **Amended** (2026-10-13, ADR-0138 D3/D4) — D9's `guest` anchor bindings resolve for anonymous requests, in the organization ADR-0138 D4 resolves; an empty set denies all.
5
5
· **Amended** (2026-10-14, [ADR-0131](./0131-total-organization-ownership-no-null-organization-id.md) D3/D13) — two of the row objects D3 renames into, `sys_position` and `sys_position_permission_set`, and the `sys_capability` D5 names, are retired by #15204 stage 8 (`66949b7729`, 2026-10-13): a position is a metadata-registry definition that names its sets in `PositionSchema.permissionSets`; `sys_user_position` stays. See the notes under D3, D5 and D8.
6
6
· **Amended** (2026-10-14, ruling of record 6159300530 on #23268, letter A) — D11's external org-wide default is retired: external visibility is the [ADR-0095](./0095-authz-kernel-tenant-layer-and-posture-ladder.md)`EXTERNAL` rung, explicitly shared rows only. See the note under D11.
7
+
· **Re-amended** (2026-10-23, ruling of record 6355206139 on #25233, letter B) — D11: externals are a population inside the member pool, by role, and reach rows through explicit grants, sharing rules and held grants' RLS included. See the second note under D11.
7
8
· **Amended** (2026-10-15, ruling of record 6181988435 on #23488, letter A) — D12's position↔set binding right and its environment-set authoring right are retired (`AdminScope.manageBindings` and `AdminScope.authorEnvironmentSets`, ADR-0049 enforce-or-remove): a position's sets and a permission set's body are environment definitions, and the definition write is `manage_metadata`'s per [ADR-0131](./0131-total-organization-ownership-no-null-organization-id.md) D3, never a delegate scope's. D12's *what* is user↔position assignments (and direct set grants) inside the subtree; read its bindings and authoring clauses as superseded by this line.
8
9
· **Amended** (2026-10-14, [ADR-0138](./0138-guest-model-anonymous-principal-doors-grants-and-organization.md) D3 item 5, ruling C of record 6159279205 on #23267) — D9's last bullet holds for `everyone` alone: a package suggests `everyone` bindings and the admin confirms each, while no door binds a set to `guest` (no package suggestion, no confirmation, no operator bind) until ADR-0138 D3 item 5's bind door is built, an act of the environment's administrator, never of a package. Read that bullet's `guest` half as superseded by this line.
9
10
· **Amended** (2026-10-17, ruling of record 6228728551 on #23960, letter B) — D12 names three kinds of administrator, tenant-level, organization-level and delegated: an organization administrator (`organization_admin` / `organization_admin_no_bypass` for the organization, not a platform administrator) creates and removes `sys_user_position` / `sys_user_permission_set` rows for that organization's members when every set the row distributes has no `*` wildcard superuser bit, no `adminScope` and only `scope: 'org'` capabilities; `admin_full_access`, platform sets, `organization_admin` itself and every delegated set stay outside, and organization-administrator status is conferred by membership grade only. Strict containment and the `everyone` / `guest` anchors are unchanged. See the note under D12.
@@ -493,6 +494,17 @@ alias tax on every API.
493
494
> separate from members (the pool below is kept). The bullets that follow record the decision as
494
495
> taken; read their `externalSharingModel` and external-OWD clauses as superseded by this note.
495
496
497
+
> **Re-amended 2026-10-23 (ruling of record 6355206139 on #25233, letter B).** In the note above,
498
+
> "drawn from an identity pool separate from members (the pool below is kept)" is replaced:
499
+
> external principals are the population inside the member pool that holds the `external`
500
+
> organization role, and they reach rows through explicit shares, share links, sharing rules, and
501
+
> the position and permission-set grants they hold with their RLS evaluated (a sharing set's
502
+
> "records related to the principal's account" is such a predicate). The bullets' "from a separate
503
+
> portal / partner identity pool" reads the same way. The last bullet's "the D6 access matrix
504
+
> gains an external-audience column" is retired: it rode `externalSharingModel`, and audience is a
505
+
> property of the principal, so a metadata-only matrix has no column to fill. The EXTERNAL rung's
506
+
> cells live in the authorization matrix gate (#25541).
507
+
496
508
Portal and partner scenarios need the Salesforce insight: internal and external record baselines
497
509
are **two different dials, and external must never be wider**. Decision:
· **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.
5
+
· **Amended** (2026-10-23, ruling of record 6355206139 on #25233, letter B) — D2: the `EXTERNAL` rung admits explicit grants only (shares and share links, sharing rules, and held position and permission-set grants with their RLS evaluated), never the OWD baseline; the resolver returns it for a holder of the `external` organization role (#25541). See the note under D2.
Copy file name to clipboardExpand all lines: docs/adr/0099-posture-adjudicated-tiering-and-external-rung.md
+27-6Lines changed: 27 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# ADR-0099: Posture-Adjudicated Tiering — one axis for tier decisions, the EXTERNAL rung's enforcement path, no explicit deny
2
2
3
-
**Status**: Accepted (2026-07-18; proposed 2026-07-17) — P0 equivalence gate landed with the acceptance (see the Acceptance addendum); P1 shipped (#3226). Amended 2026-07-18: **two-axis correction** — D2's Layer 1 tier input corrected to the per-object scope bits, original P2 superseded by P2′ (see the Amendment)
3
+
**Status**: Accepted (2026-07-18; proposed 2026-07-17) — P0 equivalence gate landed with the acceptance (see the Acceptance addendum); P1 shipped (#3226). Amended 2026-07-18: **two-axis correction** — D2's Layer 1 tier input corrected to the per-object scope bits, original P2 superseded by P2′ (see the Amendment) · **Amended** (2026-10-23, ruling of record 6355206139 on #25233, letter B) — D2's EXTERNAL column, D3 and I7: the rung admits explicit grants (shares, share links, sharing rules, held grants with their RLS) and is enforced (#25541). See the notes under D2 and D3.
4
4
**Deciders**: ObjectStack Protocol Architects
5
5
**Builds on**: [ADR-0095](./0095-authz-kernel-tenant-layer-and-posture-ladder.md) (the posture ladder + Layer 0 — Accepted, implemented; this ADR is its adjudication follow-through), [ADR-0066](./0066-unified-authorization-model.md) (superuser bypass ①; precedence), [ADR-0090](./0090-permission-model-v2-concept-convergence.md) (D10 principal taxonomy / `audience`, D11 external OWD), [ADR-0093](./0093-tenancy-mode-and-membership-lifecycle.md) (membership lifecycle — where an external principal type would come from), [ADR-0094](./0094-sys-permission-set-pure-projection.md) (one-authority precedent)
6
6
**Composes with**: [ADR-0096](./0096-execution-surface-identity-admission.md) — 0096 governs **admission** (may this call reach the engine, as whom); this ADR governs **tiering** (given an admitted principal, which tier of rows each layer grants). Orthogonal axes, deliberately separate ADRs.
|**Layer 1** (business RLS) | short-circuit (side-gated by super-bits) | short-circuit within org (side-gated) | business RLS applies (ownership / depth / sharing) |**not evaluated** — the rung's rule replaces it|
151
-
|**OWD / sharing**| n/a (already all-rows in tier) | n/a within org | OWD baseline + shares + hierarchy widening |**explicit shares only — OWD and sharing *rules* never apply**|
152
-
|**Write path**| tier does not bypass write guards: readonly strip (#2957), identity write guard (ADR-0092), Layer 0 write wall (#2946) all still apply | same | same |shares with edit access only|
150
+
|**Layer 1** (business RLS) | short-circuit (side-gated by super-bits) | short-circuit within org (side-gated) | business RLS applies (ownership / depth / sharing) | evaluated for the grants it holds (position and permission-set RLS); the member baseline's sets are never among them|
151
+
|**OWD / sharing**| n/a (already all-rows in tier) | n/a within org | OWD baseline + shares + hierarchy widening |owner-only floor on every object; shares (share links included) and sharing rules widen it; a held grant's RLS lifts the floor for its object|
152
+
|**Write path**| tier does not bypass write guards: readonly strip (#2957), identity write guard (ADR-0092), Layer 0 write wall (#2946) all still apply | same | same |same guards; the owner-only write floor (`external_default`), widened by edit shares and grant RLS as for a member|
153
153
|**Explain**| reports the carried rung — identical input as enforcement, by construction | same | same | same |
154
154
155
155
> **Amendment note (2026-07-18):** the **Layer 1** row above is corrected by
@@ -158,6 +158,12 @@ it would have caught).
158
158
> per-object `viewAllRecords` short-circuits business RLS on that object,
159
159
> tenant-walled as ever). The Layer 0 and EXTERNAL rows stand as written.
160
160
161
+
> **Amendment note (2026-10-23, ruling of record 6355206139 on #25233, letter B):**
162
+
> the `EXTERNAL` column above is the amended one. It supersedes the 2026-07-18
163
+
> note's "the EXTERNAL rows stand as written" for that column; the original
164
+
> read "not evaluated — the rung's rule replaces it", "explicit shares only —
165
+
> OWD and sharing *rules* never apply" and "shares with edit access only".
166
+
161
167
Invariants (each carries a matrix cell):
162
168
163
169
-**I1** — `TENANT_ADMIN` never crosses Layer 0. No capability composition may
@@ -178,6 +184,19 @@ Invariants (each carries a matrix cell):
178
184
179
185
### D3 — The EXTERNAL rung's enforcement path (demand-gated)
180
186
187
+
> **Amended 2026-10-23 (ruling of record 6355206139 on #25233, letter B).** The
188
+
> rung admits the channel list of [ADR-0095](./0095-authz-kernel-tenant-layer-and-posture-ladder.md)
189
+
> D2: shares and share links, sharing rules, and held position and
190
+
> permission-set grants with their RLS evaluated. Items 2 and 3 below are read
191
+
> through it: the injection rule is the owner-only OWD floor plus those
192
+
> channels, not a share-only filter, and sharing rules do apply. Item 1 shipped
193
+
> in #25541: the population is the holders of the `external` organization role
194
+
> (stage 1, #25515). An object with no `owner_id` and a public effective model
195
+
> is under no OWD for any principal, so an external holding an RLS-less grant
196
+
> on it reads every row. Explain's `guest` debugger mapping to `EXTERNAL` now
197
+
> shares the rung's name with a live population; that is harmless, because the
198
+
> guest deny-all precedes every sharing gate.
199
+
181
200
Semantics are already locked (ADR-0095 D2): an EXTERNAL principal sees only
182
201
rows explicitly shared to it; OWD baselines and sharing *rules* never widen
183
202
its visibility; misconfiguration can only narrow. What this ADR adds is the
@@ -388,8 +407,10 @@ amended rather than enforced:
388
407
-**I7 (new — the I5 dual):** the scope axis never crosses a boundary the
389
408
posture axis has not opened. A super-bit holder below `PLATFORM_ADMIN`
390
409
stays tenant-walled (enforced by P1; pinned in the matrix), and an EXTERNAL
391
-
principal's explicit-share rule replaces Layer 1 regardless of any held
392
-
bits (pinned when P3 lands).
410
+
principal's rung replaces the member baseline regardless of any held bits:
411
+
its OWD is the owner-only floor and only the grants it holds, with their
412
+
RLS, widen it (amended 2026-10-23, ruling 6355206139 letter B; pinned in
413
+
the matrix's EXTERNAL column, #25541).
393
414
-**I2 clarification:** nesting is a per-rung *floor* invariant. Additive
394
415
per-object grants widen visibility within a rung (two MEMBERs may differ)
395
416
without violating the ladder; no rung's floor exceeds the rung above.
0 commit comments