You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The urgent one. Separate from #317 (delegated / per-user) — this is the agent-principal resolver: a deployed agent authenticating to an MCP server as its own identity, not on behalf of a human. It is what actually unblocks a headless agent's mcp: no stored token — login required startup failure. In neither #317 nor #318. Authority: design-tool-registry.md §18 (§18.2 seam, §18.3 client_credentials / oauth_3lo_service, §18.4 layer split).
Problem
A deployed agent with an oauth MCP server fails at startup:
mcp: no stored token — login required: "<server>" — run 'forge mcp login <server>'
forge mcp login is laptop-only and interactive (#320) — a headless pod can't run it. #317 solves the delegated path (a human consents per session), but most deployed agents are agent-principal: they act as themselves (a service/agent identity), with no requesting human. There is no user to consent, so #317's flow can never fire for them. This is the more common and more urgent case.
What it is (§18.3)
The agent authenticates as its own identity via a resolver that needs no per-user consent:
Resolver
Principal
Standing credential
Layer
client_credentials (2LO)
the agent
client secret only
Forge (secret via broker when managed)
oauth_3lo_service (vaulted refresh)
service identity
refresh token, vaulted broker-side
initializ — AgentCore-parity path
Config declares the principal, not the flow:
auth:
type: platform # agent-principal (contrast type: user in #317)max_scope: [read]
Standalone: where the MCP server supports 2LO / client-credentials, Forge resolves it directly (client id + secret from env/secret store) — no user, no browser, works headless.
Managed: the platform's token endpoint answers POST {token_endpoint} with { server } (no subject, no user_assertion) → { access_token }; the broker holds the service refresh token (vaulted), Forge never sees it.
agent-principal: POST {token_endpoint} { server } → { access_token }
delegated (#317): POST {token_endpoint} { server, subject, user_assertion } → { access_token }
Same seam (BearerToken(server, subject, session)); agent-principal simply carries no subject/assertion. This is why the seam (#317 item 1/2) is the shared prerequisite.
Why it's the urgent path
It is the default for deployed agents (no human in the loop).
client_credentials resolver (standalone default) — client id + secret from the secret store; 2LO token request; refresh.
type: platform config + validation (and the eager-connection path at startup).
Managed: call the platform token endpoint with { server }; consume the returned access token; never hold the service refresh token.
initializ (broker):
oauth_3lo_service vaulted resolver — service refresh token vaulted broker-side, resolved per invocation (§18.4 vault).
Scope decisions per the registry entry (A6).
Authentication ≠ authorization (§18.5)
Same as #317/#318: a valid agent-principal token is necessary, not sufficient — the PDP still governs. Writes/destructive route through DEFER regardless of token validity (A9 side-effect class); the agent acting as itself does not bypass the gates. Token never enters the agent's reasoning context; broker/egress-proxy holds it and injects at egress (§17.3).
Acceptance criteria
A headless agent with type: platform + a 2LO-capable server resolves a token at startup, no browser, no forge mcp login.
Problem
A deployed agent with an oauth MCP server fails at startup:
forge mcp loginis laptop-only and interactive (#320) — a headless pod can't run it. #317 solves the delegated path (a human consents per session), but most deployed agents are agent-principal: they act as themselves (a service/agent identity), with no requesting human. There is no user to consent, so #317's flow can never fire for them. This is the more common and more urgent case.What it is (§18.3)
The agent authenticates as its own identity via a resolver that needs no per-user consent:
client_credentials(2LO)oauth_3lo_service(vaulted refresh)Config declares the principal, not the flow:
POST {token_endpoint}with{ server }(nosubject, nouser_assertion) →{ access_token }; the broker holds the service refresh token (vaulted), Forge never sees it.Token-endpoint contract (shared with #317)
Same seam (
BearerToken(server, subject, session)); agent-principal simply carries no subject/assertion. This is why the seam (#317 item 1/2) is the shared prerequisite.Why it's the urgent path
required: trueis valid here (contrastrequired: true+type: user, a config error in Epic: runtime per-user, ephemeral per-session MCP OAuth (interactive login via Slack / A2A UI) #317) — an agent-principal token can be resolved at startup, so a required server can legitimately gate readiness.Work breakdown
Forge:
client_credentialsresolver (standalone default) — client id + secret from the secret store; 2LO token request; refresh.type: platformconfig + validation (and the eager-connection path at startup).{ server }; consume the returned access token; never hold the service refresh token.initializ (broker):
oauth_3lo_servicevaulted resolver — service refresh token vaulted broker-side, resolved per invocation (§18.4 vault).Authentication ≠ authorization (§18.5)
Same as #317/#318: a valid agent-principal token is necessary, not sufficient — the PDP still governs. Writes/destructive route through DEFER regardless of token validity (A9 side-effect class); the agent acting as itself does not bypass the gates. Token never enters the agent's reasoning context; broker/egress-proxy holds it and injects at egress (§17.3).
Acceptance criteria
type: platform+ a 2LO-capable server resolves a token at startup, no browser, noforge mcp login.required: true+type: platformgates readiness correctly (server reachable ⇒ ready).Related
#317 (delegated
type: user— shares the seam) · #318 (delegated broker / ID-JAG) ·initializ/aip/mcp-delegated-identity-broker.md(add theoauth_3lo_servicevaulted resolver) · #316 (discovery/DCR) · authoritydesign-tool-registry.md§18.