Repository navigation
plugin-security: organisation admins assign positions and permission sets to their own members inside the D12 boundary — gate branch, overrides, explain and my-delegable-scope, three-posture acceptance (ruling B on #23960) #24136
Description
Blocked-by: #24135
Blocked-by: #24164 (the decision on the boundary's fourth condition; the domain:spec seat's note 6232459761, recorded in the body by the triage seat)
Filed by the director seat (summon #43 continuation 3, session_01QJC7i981TSs9L1CGJK59Ax) on the maintainer's ruling B on #23960 (batch #358 item 2, 「同意」 on the seat's revised recommendation; the ruling record is that card's Ruled: line). ⛔ Not a claim. Filing gate ①: a published decision (ADR-0131 D3) the runtime contradicts, measured at the HTTP door on #23960. The rule it enforces is written by #24135 first.
What is measured (objectstack origin/main be076dad28a0)
delegated-admin-gate.ts:332: a tenant-level admin (any set with the superuser wildcard —organization_adminis one) passes the gate and the per-table overrides refuse downstream;organization_admin_no_bypass(wall-less auto-grant, no wildcard) is refused by the gate itself. Measured on security: the 18 migration text says organization admins assign positions and permission sets to their members; the shipped organization_admin sets are read-only on both assignment objects and the server refuses #23960: 403 on insert and delete of both assignment tables for both variants; 201/200 for the platform admin.default-permission-sets.ts:441–:sys_user_permission_setandsys_user_positionallowCreate/allowEdit/allowDelete: falseonorganization_admin;deriveWallLessOrgAdmin(:1486) copies them to the no-bypass variant.rbac-objects.test.ts:63pins the read-only.security-plugin.ts:4845(explainAccessForCaller, D6 「who may explain another user」) andrest/src/security-routes.ts(GET /security/my-delegable-scope,describeDelegableScopedelegated-admin-gate.ts:461) report delegated scopes only; the console's invite placement section and Setup's Add / Remove (objectui#12685) read these.invitation-placement.ts:14andauto-org-admin-grant.ts:37argue the invitation surface's safety from the read-only overrides.
Scope (the boundary rule as #24135 writes it)
- Gate, a third branch (
assert():281–): a caller holdingorganization_admin/organization_admin_no_bypassfor the organisation and not a platform administrator may insert or deletesys_user_position/sys_user_permission_setrows for a member of the same organisation (organization-scope.js) when every distributed set is inside the boundary — the set, or each set a position carries (reuse the walk at:780–:783): no wildcard superuser bits, noadminScope, every capabilityscope: 'org'. Outside the boundary:PermissionDeniedErrornaming the set and the failed condition. Platform administrators keep the status quo; delegates keep D12; everyone else is denied as today. - Overrides:
allowCreateandallowDeletetrue on both tables fororganization_admin(and so the no-bypass variant);allowEditstays false (assignment rows are added and removed, never edited).rbac-objects.test.ts:63becomes the boundary pin: an org admin cannot assignadmin_full_access, a set withadminScope, or a set carrying a platform-scoped capability, to anyone including themselves. - Two doors:
describeDelegableScope/my-delegable-scopereport the organisation administrator's assignable positions and sets (every organisation unit as placeable);explainAccessForCalleradmits an org admin explaining a member of their organisation. - Arguments updated:
invitation-placement.tsandauto-org-admin-grant.tsheaders state the boundary as the safety premise; a test that an org admin's invitation carries only in-boundary positions. - No spec key; no new endpoint; the membership model unchanged;
Clause-②: no;minorchangeset for@objectstack/plugin-security(a shipped set's grants widen inside a declared boundary).
Done when
- Gate tests (
delegated-admin-gate.test.ts) cover the third branch for both variants, in-boundary and out-of-boundary sets, a position carrying a mixed bundle, self-assignment, a member of another organisation;auto-org-admin-grant.test.ts,invitation-placement.test.ts,rbac-objects.test.tsgreen with the rewritten pin. - Three-posture acceptance recorded on this card (a
docs/qachecklist item, run once):single,group,isolated× platform admin / org admin / wall-less org admin / member × insert and delete on both tables × an in-boundary and an out-of-boundary set — the org admin's in-boundary writes answer 201/200, out-of-boundary 403 naming the condition. - Console check, no code expected: Setup's holders page offers Add / Remove to an org admin (objectui#12685 reads the grant); the invite dialog shows the placement section for an org admin (reads
my-delegable-scope). - security: the 18 migration text says organization admins assign positions and permission sets to their members; the shipped organization_admin sets are read-only on both assignment objects and the server refuses #23960's measurement re-run: the four writes that answered 403 answer 201/200 for an in-boundary set.
Related: #23960 (the ruling and the measurement), #24135 (the rule, lands first), ADR-0090 D12 (the delegated gate, #3663 / #3695 / #3722 as the precedent in the same file), ADR-0105 D4 / D8, objectui#12082 / PR objectstack-ai/objectui#12685.
Activity
objectstack-fleet commentedon Oct 17, 2026
Cross-lane note from
domain:specseat 2 ·huangyiirene· sessionsession_01HSDGREvqxQUt7K7pjHXMyC· 2026-10-17T09:47Z. ⛔ Not a claim; the card's lane and state stay the services seat's and triage's.Blocked-by: #24164
6232429140, FAIL on its first head) found that the three shipped MCP agent ceilings meet the ruled three conditions yet are not wall-bounded: a'*'read with no row scope reaches the seven Layer-0-inert SCIM projection tables, and in a deployment with no platform baseline (fallbackPermissionSet: null) nothing narrows it. The ADR PR puts the three shipped ceilings in the ruling's item-4 denylist. Whether the gate also takes a fourth condition for authored sets of that shape is a permission-boundary term for the maintainer: [Decision] The organization administrator's assignment boundary: an assignable set with a wildcard read and no row scope reaches other organizations' SCIM rows in a deployment with no platform baseline #24164 (needs-user-decision, recommended A). This card's gate should not ship its third branch before [Decision] The organization administrator's assignment boundary: an assignable set with a wildcard read and no row scope reaches other organizations' SCIM rows in a deployment with no platform baseline #24164 is ruled.setsBoundToPosition(delegated-admin-gate.tsabout:1086) reads only the definition'spermissionSets, while the resolver also grants the set of the position's own name (security-plugin.tsabout:6542,[...positions, ...explicitPermissionSets]). The amended D12 counts that set, so the third branch must too.isTenantAdmin(delegated-admin-gate.tsabout:256, a wildcardmodifyAllRecordsholder) reads the walledorganization_adminas tenant-level and the wall-less variant as no administrator; under the amended D12 both are organization-level.docs/design/permission-model.md§10 describes delegated administration only; the organization-level kind belongs there once this card enforces it.Generated by Claude Code