Decision
ADOPT + TEST — add fixture-only, provenance-bound MCP OAuth scope step-up behavior to Agent Factory/EventRelay. Keep live authorization disabled.
Verified upstream change
The official TypeScript MCP SDK added per-operation OAuth scope challenges on September 16, 2026:
The SDK now supports scopeChallenge for tools, static/template resources, and prompts, returning HTTP 403 insufficient_scope with WWW-Authenticate before handler execution or SSE starts. The challenge should contain the minimal complete scope set required for the current operation.
Official conformance coverage is proposed but not yet merged:
Do not claim official conformance until that upstream work merges and EventRelay pins and executes it.
Why this matters
Agent Factory needs a safe way to pause an operation, request narrowly scoped authority, record the decision, and retry without treating model-generated content as authorization. This is directly relevant to tool execution, resource reads, prompt access, and durable EventRelay receipts.
A critical SDK boundary is that the scope callback runs before input-schema validation/transformation. Any request field used for dynamic authorization therefore needs explicit canonicalization and validation with the same semantics as the eventual handler.
Fixture-only implementation
- Add a feature-flagged scope-challenge adapter with live OAuth disabled by default.
- Cover tools/call, static and template resources/read, and prompts/get.
- Return HTTP 403 before handler invocation or streaming when scopes are insufficient.
- Emit the minimal complete required scope set and verified
resource_metadata.
- On the client path, union prior grants with newly challenged scopes before a fixture-only retry.
- Record immutable receipts containing call ID, operation and target, prior scopes, challenged scopes, resource metadata, approval provenance, decision, retry result, and whether the handler ran.
- Bind approval to exact operator, operation, target, scope set, resource, expiry, and revocation state.
- Treat a challenge as a request for authorization—not authorization itself.
Security invariants
- Model output, peer-agent messages, tool results, Skills content/cache metadata, Video Pack transcripts/OCR, mission-canvas text, and generated workspace files grant zero authority.
- Validate and canonicalize dynamic scope inputs before policy evaluation.
- Deny malformed identifiers, scope-confusion/hierarchy assumptions, incorrect resource metadata, canceled or revoked grants, and peer-agent “GO” instructions.
- Reject repeated incremental challenges for a single operation; challenge once with the complete required set.
- Prove the protected handler and any side effect did not execute before authorization.
- No automatic spending, deployment, messaging, merge, or external write authority.
Acceptance criteria
Boundaries
No production activation, live OAuth exchange, provider spending, deployment, or merge is authorized by this issue.
Estimated effort: 1–2 engineering days.
Decision
ADOPT + TEST — add fixture-only, provenance-bound MCP OAuth scope step-up behavior to Agent Factory/EventRelay. Keep live authorization disabled.
Verified upstream change
The official TypeScript MCP SDK added per-operation OAuth scope challenges on September 16, 2026:
The SDK now supports
scopeChallengefor tools, static/template resources, and prompts, returning HTTP 403insufficient_scopewithWWW-Authenticatebefore handler execution or SSE starts. The challenge should contain the minimal complete scope set required for the current operation.Official conformance coverage is proposed but not yet merged:
Do not claim official conformance until that upstream work merges and EventRelay pins and executes it.
Why this matters
Agent Factory needs a safe way to pause an operation, request narrowly scoped authority, record the decision, and retry without treating model-generated content as authorization. This is directly relevant to tool execution, resource reads, prompt access, and durable EventRelay receipts.
A critical SDK boundary is that the scope callback runs before input-schema validation/transformation. Any request field used for dynamic authorization therefore needs explicit canonicalization and validation with the same semantics as the eventual handler.
Fixture-only implementation
resource_metadata.Security invariants
Acceptance criteria
WWW-Authenticatechallenge.Boundaries
No production activation, live OAuth exchange, provider spending, deployment, or merge is authorized by this issue.
Estimated effort: 1–2 engineering days.