Experimental MCP service
This branch provides a native Go Streamable HTTP gateway and an API-owned OAuth
broker adapted from architecture-reset. The gateway uses generated OpenAPI
types and calls the current Go API. The broker uses oidc-provider and
openid-client for OAuth and AAI federation.
The contract guide defines tool parity, inputs, scopes, command recovery and the private assertion protocol.
Process boundaries
The gateway retains no session or business state. The broker persists OAuth grants, sessions, clients, immutable Party bindings and single-use upstream login state in its own PostgreSQL database. Its signing keys, cookie keys and database must persist across restarts and be shared by broker replicas. Runtime code checks its restricted database role and performs no migration.
OAuth accounts include the exact AAI identity, canonical Party, captured generation and operator enrolment in their immutable identity. Refresh rechecks the API and fails after a change. Every protected API invocation independently checks Party eligibility, generation and AUP. Browser logout revokes browser sessions; OAuth revocation uses the broker's advertised revocation endpoint. Already issued OAuth access tokens last up to ten minutes, with immediate owner generation and operator checks at the API. Revoke the refresh token to prevent future token issuance, then discard the client's access token. The broker's stateless JWT access tokens cannot be individually revoked through the revocation endpoint; they retain their signed expiry and owner checks.
Enrolment
The optional MCP laboratory profile
provides coordinated HTTPS routes, a dedicated OAuth database, persistent keys
and a local AAI client registered with the exact /interaction/callback URI.
See client setup for its explicit
OAuth enrolments. Existing deployments keep MCP disabled until they select this
development-only profile. The identity must already be registered in Pharos
with current AUP.
The enrolled AAI callback remains /interaction/callback. It performs an
expiry-aware, non-consuming state lookup and redirects within the broker origin
to that interaction's callback path. The browser then supplies its original
scoped signed cookie. Cookie, path and upstream state must agree before the
single-use code exchange, which uses the original enrolled redirect URI.
Concurrent interactions retain separate cookie paths; callback relays use
no-store and no-referrer.
The query-free consent page uses same-origin referrer policy so a native
browser form supplies the exact broker Origin. Consent continues to refuse
missing, opaque or foreign origins and non-form content types. The policy sends
no referrer to another origin; sensitive callback responses retain no-referrer.
Its form CSP permits the broker and the current client's provider-validated
callback origin so approval and denial can reach a separate native listener.
Other origins remain blocked; callback URLs never supply raw CSP text.
Keep the API identity endpoint private. Preserve the advertised public Host when proxying the gateway and broker. Do not expose the internal API assertion audience as an alternative OAuth resource.
All secret settings support direct values or their _FILE variants; use one
form per setting. Every process currently requires APP_ENV=development or
isolated APP_ENV=local. HTTPS is required. Isolated HTTP fixtures additionally
set MCP_ALLOW_HTTP=true; the API uses its existing authentication HTTP gate.
The existing API authentication enrolment remains required. Add:
Gateway configuration:
Broker configuration:
Broker and gateway signing keys must differ. Enrol new public keys before rotating signers; retain retiring verification keys for the longest outstanding token lifetime. API browser-attestation and session credentials retain their separate authority.
Database and commands
An administrator creates a dedicated broker database and separate migration and runtime roles. Revoke public database access, grant only CONNECT to runtime, and run the migration separately:
The migration command requires MCP_BROKER_MIGRATION_DATABASE_URL, which must
never enter the running broker container. Afterwards grant runtime USAGE on
mcp_oauth, SELECT/INSERT/UPDATE/DELETE on artifacts, SELECT/INSERT on accounts,
and SELECT/INSERT/DELETE on upstream_login_states. Runtime must have no database
or schema CREATE privilege, superuser, role creation, database creation or RLS
bypass rights. Deny it access to other application databases.
Start the configured broker and gateway in separate terminals:
The gateway's /healthz is a liveness endpoint. OAuth discovery is published at
/.well-known/oauth-protected-resource/mcp; unauthorised MCP requests include
its URL in WWW-Authenticate. The broker publishes ordinary OAuth/OIDC metadata
and /health/live, /health/ready (including its database permissions).
MCP clients connect to the public /mcp URL and follow OAuth discovery.
Build images from the repository root:
Verification
pnpm verify includes generation drift, architecture boundaries, Go race tests,
broker TypeScript compilation and OAuth/AAI fixtures. The SDK fixture performs
initialisation, scoped discovery and generated HTTP calls. Write fixtures cover
exact command identity, invalid input, redirects, bounded replies and uncertain
outcomes. AAI fixtures validate signatures, issuer, audience, nonce, PKCE and
exact stable identity across ID token and UserInfo.
Run these infrastructure lanes on the configured dev box or build runner, in a separate checkout:
The broker lane runs the OAuth journey against real PostgreSQL and tests
immutable generations and concurrent single-use consumption with a restricted
role. The browser lane needs Chromium (pnpm exec playwright install chromium)
and runs real scoped-cookie redirects, approve/deny form submissions to a
separate native callback server, unrelated-origin CSP rejection and PKCE code
exchange against the broker with disposable AAI and Party fixtures.
The authentication CI workflow runs this browser lane. Party lanes exercise
the owner query and existing authority boundaries.
These are disposable fixtures. External AAI, desktop MCP client consent screens,
production proxy behaviour and the deployed business journeys remain separate
qualification.
Page source
Source snapshot ยท Revision f928834c8.