Skip to content

Slice 062: MCP authorization (client role, resource server, personal-profile AS) - #60

Merged
HackTuah merged 13 commits into
mainfrom
slice/062-mcp-auth
Sep 22, 2026
Merged

HackTuah merged 13 commits into
mainfrom
slice/062-mcp-auth

Conversation

@HackTuah

Copy link
Copy Markdown
Member

Slice 062: MCP authorization, in every role, above beam_mcp's core (ADR-0007 decision 8; ADR-0008
decision 4: identity is not authority).

Three profiles. :local is 061's static bearer on the loopback, unchanged and still the
default. :production makes Trinity an OAuth 2.1 resource server against the external
authorization server a deployment names: RFC 9728 metadata, 401 with a challenge, JWT validation
against the issuer's JWKS (iss, aud holding this server, exp, nbf, an allow list that
excludes none and every shared-secret algorithm) or RFC 7662 introspection for opaque tokens.
Trinity issues nothing there and holds no signing key. :personal adds a small authorization
server for the owner's own machine: RFC 8414 metadata, code + PKCE (S256), RFC 8707 resource,
RFC 9207 iss, CIMD with DCR behind a flag, ES256 tokens of ten minutes, rotation by kid.

The owner's three constraints, as properties the tests hold. No tool dispatch without an
audience-bound token and a host gate (scope is checked before the gate and is never an allow rule).
No token material in the model context (the boundary answers a principal, never the token; a census
holds that one function reads the Authorization header). Receipts name issuer, subject and scope,
on refusals and on calls that run.

Trinity is not the issuer of production authority. The personal profile refuses to start under
an external authority adapter, and every token it mints carries a mark the production profile
refuses whatever key signed it. Enterprise Managed Authorization left the slice under the owner's
decision of 2026-09-22 and is recorded as a deferral with a lift condition (NOTES, "Amendment");
AC3 and AC6 are removed from the acceptance criteria.

Client role. On a 401 naming resource metadata the /mcp page offers "authorize"; the flow
runs with PKCE and a resource indicator, the callback checks iss, and the token is stored per
resource at mode 0600. 060's driver presents it and performs no flow of its own, by census.

Proof: slices/062-mcp-server-auth/PROOF.md (AC1, AC2, AC4, AC5, AC7, AC8, each with its command
and output; the boundary refusal and the census red are pasted from their runs). Gate green locally
and on CI across the SQLite, Postgres and FIPS legs.

… the issuer question

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ersonal), the host, the plug's 401 with a challenge, the principal in the context and the receipts, scope before the gate, the OAuth endpoints and the client role's callback

Signed-off-by: Ayla Croft <aylacroft@proton.me>
Signed-off-by: Ayla Croft <aylacroft@proton.me>
…pts name the principal; no token material

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…+ PKCE + resource, iss on the redirect, the RS accepts its own issuer); DCR 404 unless enabled; rotation strictly newer; a loopback CIMD document over http; the JWKS miss floor wired

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…, the one reader of the header), AC8 (the client role against the fake AS: 401 to challenge, PKCE, the token stored 0600 and presented, the RS accepts it; wrong iss refused; DCR once), introspection (RFC 7662), the configuration's refusals, the personal profile refused at boot under an external adapter, no key material in production; the fake AS's token endpoint kept its state; the client clears its challenge on connect

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…ze', which begins the client role's flow and sends the owner to the authorization server

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…he owner's decision (AC3, AC6 removed; the profile table); the recovery, the deviations and the findings in NOTES; docs 01, 06, 07, 08, 09, mcp-server and the README as built; TRINITY_MCP_AUTH_* in runtime.exs; the ROADMAP row and its change-log line

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…the MCP supervisor, not linked to its booter (the suite found it dying with the test process); the gate's readability and complexity findings (the claim checks in three named steps, the key lookup flattened, the fake AS's route table, alias order); sobelow's traversal findings on the host's own paths, each with its reason

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…package is a top-level boundary, since a sub-boundary inherits its ancestors' deps and the empty list under Trinity.MCP was a claim the compiler never checked; Trinity.MCP names it as a dependency, the planted line is a fixture and the refusal is PROOF's

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…1, AC2, AC4, AC5, AC7 and AC8 (AC3 and AC6 removed); the boundary refusal and the census red, each pasted from its run; the consent page and the live endpoints under proof/

Signed-off-by: Ayla Croft <aylacroft@proton.me>
…rce server, personal-profile AS)

Signed-off-by: Ayla Croft <aylacroft@proton.me>
Signed-off-by: Ayla Croft <aylacroft@proton.me>
@HackTuah
HackTuah merged commit 9859fbe into main Sep 22, 2026
8 checks passed
@HackTuah
HackTuah deleted the slice/062-mcp-auth branch September 22, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant