Chapter 8 — Security and tenancy¶
Who can do what, enforced where. Rosetta's security story is layered rather than monolithic: an organizational boundary, a key-management system, a tenancy model, a tool policy, and a set of structurally human-only acts. This chapter walks the layers from the outside in.
8.1 The organizational boundary¶
Repository access itself is governed (DT-RX-024, ratified and shipped): the GitHub organization runs base-permission none, with a single insiders team as the boundary — a small maintainer core across the constellation repos, named outside collaborators with read access on a subset, and the evidence archive restricted to insiders only. The docs site mirrors the same boundary: the internal build is gated on the same insiders membership (DT-RX-029). One boundary definition, applied to code, evidence, and documentation alike.
8.2 Identity and the KMS¶
Humans and agents authenticate differently, on purpose:
- Humans register at the console under a fail-closed, data-driven domain allow-gate (DT-RX-031): registration is permitted only when the applicant's verified email domain is admitted in the tenancy data, resolved through the API server — if the gate cannot be evaluated, registration refuses. Admitted users are auto-assigned to their tenant account by verified domain. Sessions exist only in the console BFF; the API server never sees a cookie.
- Agents and tools carry
rsk_API keys minted by the human in the console: 40-hex-char secrets stored only as bcrypt hashes with a short prefix index, scoped (read,context:retrieve,plugin-install, and a privilegedimpersonatefor service keys acting on behalf of users), revocable individually or wholesale, with every authenticated request asynchronously audited. The API surface is Bearer-only;/healthis the single anonymous route. - Distribution is part of the perimeter: the install routes serving plugin bundles
and MCP binaries require a
plugin-install-scoped key with no session fallback — the supply chain rides the same KMS as the API.
8.3 The tenancy model¶
Tenancy lives in MySQL and is enforced in one authorization package on the API server:
- Accounts hold users; account roles rank
owner > admin > member > viewer, with owner/admin granted account-wide sight. - Engagements partition knowledge. Access is an account-wide role or an explicit
per-engagement grant (by user or account); the engagement creator is atomically
granted
leadat birth. Denial is always 403, never 404 — the API does not leak existence through error codes. - Graph-side partition isolation is enforced independently by schema and gates:
engagement-scoped nodes
BELONGS_TOtheir engagement, intra-engagement edge families require both endpoints in the same engagement, a foreign-owner apply draws a 409, and the client↔engagement linkage is invariant-gated. Tenancy is thus checked both at the door (authz) and in the data (invariants). - The platform tier (cross-tenant administration: domain admission, account and member mutation, admin grants, stranded-user reassignment) is a separate gate on a dedicated table, with last-admin revocation refused under row lock — and the entire platform-admin API family rides tool-policy-denied tags, so none of it is reachable from the agent surface.
8.4 The agent boundary¶
The MCP tool policy is the security layer most architectures don't have: a
deny-by-default allowlist over the generated tool surface, with a completeness guard
that fails the build when a new API tag appears in neither the allow nor the deny list.
At snapshot the denied set spans the tenancy and operator families (accounts,
account-members, platform-admin, engagement-access, export, presence,
twin-ratification) plus three explicitly denied operations. Above the policy sits
the plugin write-safety contract (confirm-before-destructive, idempotency, the
simulated-content routing rule, no raw API access); below it, the server enforces the
same boundaries again (scope checks, authz, 422 enum validation). An agent that
misbehaves has to defeat three independent layers, each recorded.
The clearest expression of the design is ratification (Chapter 5, stage 6): the one act that turns simulated into confirmed and agent-authored into human-ratified is absent from the tool surface, refused to API-key principals by the console routes, and stamped with a human identity — a structural human gate, not a procedural one.
8.5 Data honesty as a security property¶
Rosetta treats provenance as part of its trust boundary, and the assessment endorses that framing: a governed-knowledge platform whose simulated content could masquerade as confirmed would be insecure in its actual threat model — which is bad knowledge reaching a customer document with the platform's authority behind it. The lanes (Chapter 2 §2.5), the rehearsal quarantine, the customer-tone hard-fail, and the ratification gate together form the integrity half of the security story, and the open bitemporality work (DT-RX-033) extends it to when a fact was believed — invalidate, never overwrite.
The measurement system next: Chapter 9.