--- id: AUTHZ.1 status: ratified ratified: 2026-09-01 (Jason Woltje; PRD rev1 ratification PR) --- # AUTHZ.1 — Capability authority, enforcement, and accepted risk The agent-side authority model: what binds a seat, where it is enforced, what is closed by construction, and what is accepted as residual risk. Sources: the L2 authorization contracts, `mosaic-core` (measured 2026-08-31), and the lane's `AUTHORIZATION-GAPS.md`. ## Glossary **Privilege escapation** *(Jason, 2026-08-31)* — the outcome class in which an agent exercises authority it was never granted, regardless of mechanism. Deliberately collapses escalation and misdirection: the outcome is identical; the distinction matters only when choosing a control. ## Authority composition is pure intersection ``` role capability ceiling ∩ assignment scope ∩ lease scope ∩ workflow state ∩ target policy ∩ trusted backend availability = effective capability grant ``` No operation adds capability. Only an authenticated principal with role-management authority may create, edit, activate, bind, or roll back roles (L2-D13); agents cannot, ever. Orchestrators cannot deploy seats at all — coordination goes through `mosaic coord` requests to the coordinator service (register OD-08/OD-09). Cycle detection is unnecessary because no grant edge exists. ## Enforcement point: `mosaic-core` A tracked, non-npm Pi extension loaded via role-scoped settings. Per seat, per launch: trusted-path manifest load (`/fleet/roles//mosaic-core.manifest.json` — committed, non-symlink, role cross-checked), fail-closed state machine (`not-applied | applied | fail-closed`), exact active-tool reconciliation, per-call interception with read containment (canonicalization + realpath + credential-path deny), per-incarnation append-only journal. Capabilities C1–C8 are the authority; tools are their bound projections; `tools[]` must equal the bound bindings exactly. The capability map is closed and hardcoded in the canary phase (gap G7 — by design for now; L2-D21 is the end state). ## The firewall rules 1. **Agents never reach role-management surfaces** (L2-D13). A seat that can invoke role management can self-grant, voiding the model. 2. **The coordinator is a service, never a seat** (gap G4; register OD-08). A coordinator-as-seat turns the intersection chain into a cycle. ## Closed vs accepted **Closed by construction: escalation.** The intersection chain admits no capability-adding edge. **Accepted within reason: misdirection.** A rogue or colluding orchestrator can still *route work* to a seat that already legitimately holds a capability. The authority is genuine, so no structural control can refuse it. Jason's ruling: escalation and misdirection are tiered **by outcome — identically**; locking down far enough to mechanically prevent misdirection cripples the system to inoperability. Mitigation posture: **audit and visibility, not prevention** — see the audit surface in [[UI.1-webui-surfaces]] and gap G3 below. ## Role separation as the working mitigation Design intent (not yet enforced by any manifest — gap C3 in the lane ledger): | Role | Must NOT | |---|---| | coding agent | create remote git repositories | | gate agent | code | | review agent | code | | interact agent | code, create remote repositories | Breaking the monopoly means no single seat holds an exit path; escape requires inter-seat coordination, which is exactly what the audit exists to catch. Register OD-25–OD-34 (review/gate/arena families, independence rules) carry the role taxonomy this matrix projects onto. ## Gap register (measured 2026-08-31) | ID | Gap | Status | |---|---|---| | G1 | No least-privilege language anywhere in L1/L2/NORTH-STAR (grep-verified) | **L2-D52 amendment drafted** | | G2 | Assignment issuance criteria unspecified (renewal names criteria; issuance does not) — full-ceiling requests validate cleanly | **L2-D52 amendment drafted** | | G3 | No misdirection audit exists — no tooling, agent, or surface | open → [[UI.1-webui-surfaces]] §Audit | | G4 | Coordinator-as-seat would collapse the model | firewall — never violate | | G5 | Seat config mixes authority classes (role binding beside a model dropdown) | open → [[SEAT.1-seat-profile]] | | G6 | `role-harness-config/DESIGN.md` scope defect (unstated surface) | fix drafted (amendment in `proposed/docs/`) | | G7 | Capability map closed/hardcoded | by design (canary phase) | Amendments staged in `proposed/docs/` per the lane convention; ledger items A3/A4 track ratification. The auditor-identity question (an auditor agent is itself a seat, itself subject to misdirection) is on the grill: [[GOV.5-open-questions]] Q-A1. ## E2 inputs (triage 2026-08-31; see [[GOV.2-docs-inventory]]) **Canonical ground truth**: `DEVELOPER-GUIDE/architecture/mutator-class-gate.md` (the default-deny whole-class gate this section's language must match), `lease-broker-protocol.md` + `lease-broker-security.md` (incl. the named promote-lease-lost-ACK residual), `ADMIN-GUIDE/security/discord-ingress.md` (the one implemented admission/role model). **Pending pulls**: DRAFT S2 `rbac-grant-model.md` (granular RBAC per rev0 §4). ## S2 contract feed (extraction 2026-08-31) Full extraction record: lane `S2-EXTRACTION-2026-08-31.md` (per-contract cores, dependency edges, ruling cross-checks). Pulls binding on this section: - **Three-layer authority (contract 2)**: platform role (member/admin, instance administration only, **no implicit tenant access** — two live admin bypass paths named non-conformant and scheduled for retirement: `command-authorization.service.ts` admin short-circuit, `mcp.service.ts` scope derivation); hierarchy grants (viewer/member/owner, deny-by-default, down-chain, effective = max, live fail-closed); workspace membership (its own mechanism, REQ-ID-001). The layers are non-substitutable. - **Agents are not a valid grant subject** — grant subject is exactly-one-of user_id/team_id. Structural enforcement of the agents-never-reach-role- surfaces ruling, stronger than policy. - **Consent ≠ authorization (contract 7 §5.7)**: consent records govern agentic/feature data access, are distinct from hierarchy grants, and confer no platform authorization; default-deny with **no platform-admin bypass**; consent mutation is subject-only (admins refused at write time). - **Bounded revocation propagation**: next authz decision denies; open Socket.IO connections re-evaluated within 30s or next inbound message. - **company-CRUD capability**: platform-scoped, admin-assigned, audited delegation of exactly one visibility-mutation command (`platform_capabilities` table) — the model's template for narrow capability delegation. - **Membership locality + no-existence-oracle (contract 8 §3)**: member-readable workspaces contribute only at their own node, never promoted upward; unreadable vs nonexistent are byte-equivalent. ## Audit implementation ruling (Q-A1/Q-A2, Jason 2026-09-01) The authorization audit is **mechanical tooling**: deterministic checks over the grant/assignment record, witness-style (the S2 writer-coverage pattern), feeding the audit page read-only. Agents may consume audit output but never produce the verdict — prompt adherence is not an enforcement mechanism. Q-A2 (who audits the auditor) dissolves: the auditor is code, audited by ordinary review and CI.