Repository navigation
test(factory): add provenance-bound MCP OAuth scope step-up fixtures #2005
Description
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:
- SDK commit: modelcontextprotocol/typescript-sdk@6032170
- Core SEP-2350 precedent: modelcontextprotocol/modelcontextprotocol@443f75d
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:
- Issue: Add server conformance for SEP-2350 scope challenges modelcontextprotocol/conformance#480
- Draft implementation: feat(server): add SEP-2350 scope challenge scenario modelcontextprotocol/conformance#481
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
- Deterministic fixtures for all supported primitive types.
- Low-scope request produces 403 plus a correctly formatted
WWW-Authenticatechallenge. - Full-scope retry succeeds and invokes the handler exactly once.
- Negative-input and provenance-isolation matrix passes.
- Machine-readable receipt distinguishes configured policy, observed enforcement, and exclusions.
- Current SDK commit is pinned for fixture evidence.
- Upstream conformance PR docs(triage): PR remediation matrix — 2026-07-03 refresh (16 open PRs) #481 is tracked as unmerged and excluded from any official-conformance claim.
- CI, security, CodeQL, coverage, dependency, and secret checks pass.
Boundaries
No production activation, live OAuth exchange, provider spending, deployment, or merge is authorized by this issue.
Estimated effort: 1–2 engineering days.
Activity
linear-code commentedon Sep 18, 2026
GRV-597
github-actions commentedon Sep 18, 2026
👋 Thanks for opening this issue! It has been automatically labeled for triage.
kk-agent commentedon Sep 28, 2026
Max-aggressive cleanup 2026-09-28: EventRelay/UVAI product work is PARKED. Closing this stale/open item. Reopen if Hayden unparks the cut.