SEP: HTTP Message Signing for MCP Client Authentication#2752
Conversation
Adds a draft SEP proposing RFC 9421 HTTP Message Signatures as an optional, additive proof-of-possession client-authentication mechanism for MCP. Supersedes the dormant SEP-1415 with technical-feedback fixes: correct RFC 9421 component/parameter semantics, prohibition of the `alg` parameter, Accept-Signature negotiation, nonce-based replay protection, Signature-Agent key distribution for init-less mode, and a stable-identity `tag` that survives key rotation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per SEP-1850, rename the file from 0000- to 2752- now that the PR number is known, and update the header to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Reformatted the SEP markdown per prettier (italics, table spacing). - Ran `npm run generate:seps` to produce docs/seps/2752-*.mdx and update docs/seps/index.mdx + docs/docs.json. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructures Client behavior into §4.1 (Signer abstraction) and §4.2 (Requirements). Explicitly states that RFC 9421 doesn't constrain *where* signing happens, and enumerates valid signer locations: in-process non-extractable, OS keychain, ssh-agent-style local broker (ssh-agent / gpg-agent / authsome), hardware tokens, remote KMS. Addresses the threat model raised by @zriyansh in discussion modelcontextprotocol#2797: PoP at the protocol layer does not by itself defend against an LLM that can be coerced to print env vars or shell history, but pairing PoP with an out-of-process signer (where the agent process never holds the key) does. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…/njdawn/modelcontextprotocol into feature/sep-http-message-signing
This comment was marked as spam.
This comment was marked as spam.
|
Thank you @njdawn for picking this topic up again. Regarding the identity and the key management of the client: Currently, there are multiple concurrent RFC drafts in place, addressing this topic. One of these is the HTTP Message Signatures Directory from the Web Bot Auth WG, which I mentioned in the closed SEP and which you adopted here. Another option comes from the WIMSE WG. In the WIMSE Workload-to-Workload Authentication with HTTP Message Signatures, WIMSE profiles HMS and introduces a And yet another option comes from @dickhardt in the recent AAuth draft. All of them have their strength and weaknesses. E.g. AAuth and Web Bot Auth directory do not require a central identity management system, but the WIMSE approach does. AAuth is an extension for OAuth2, while the others are not. Etc. Given that, it would be helpful to more explicitly position this proposal:
|
While this is true, this issue can also be addressed by making use of DPoP or MTLS based PoP. None of these two are capable of establishing a separate identity for the agent. There are only about PoP. The aim of the closed SEP, and in my understanding, also of this one, is to go beyond pure PoP, and to enable each party in the chain to understand the identity and authority not only of the last caller, but of every actor in the call chain. This IMO will ultimately allow building some sort of PIC model to defeat the confused deputy problem everybody is looking for. |
This comment was marked as spam.
This comment was marked as spam.
|
Thanks @dadrus — this is the right question to settle before asking for a sponsor, and your "centralized identity is problematic in the agentic world" point is the one I want to design around. Position: pluggable on identity & key discovery, opinionated only on the wire profile. This SEP should specify how a request is signed and verified — covered components, the Concretely, I'd like to reframe §2.6 ("Key distribution") as an extensible set of key-resolution methods over the same signing profile:
So the answer to your three options is "the third, deliberately": multiple approaches, but with a decentralized default rather than a neutral one — On the call-chain identity / confused-deputy thread with @chopmob-cloud: I agree that's the deeper prize, but I think it belongs above this PoP layer, not inside it — the SEP scopes authorization out (§"What this SEP does not address"). What this SEP should do is leave the right hooks: the stable I've added an "Identity model & extensibility" subsection making the key-resolution-method registry explicit, with |
|
Thanks @chopmob-cloud — the re-serialization failure mode is real and worth addressing explicitly: RFC 9421 I want to keep the baseline byte-exact and add JCS as an opt-in, rather than swap the default:
I've added this as an optional negotiated component (§2.7) and cited draft-hopley-x402-payment-evidence-frame as prior art for the covered-components design. Your |
…edback) Addresses the review thread: - §2.6 reframed as an extensible registry of key-resolution methods over a fixed signing profile, with an "Identity model & extensibility" subsection. Signature-Agent (Web Bot Auth) is the MUST baseline (decentralized default); WIMSE Workload-Identity-Token and AAuth are registered optional methods for centrally-managed identity (per @dadrus). Call-chain attribution stays out of scope; tag + content-digest are the hooks a PIC/receipt layer binds to. - §2.7 adds an optional, capability-negotiated JCS (RFC 8785) content digest for re-serializing relay topologies, with the RFC 9530 byte digest as the MUST baseline (per @chopmob-cloud); cites the x402 payment-evidence-frame draft. - §3.1 capabilities gain keyResolution + contentDigest negotiation fields. - References: RFC 8785, WIMSE, AAuth, x402 PEF.
Seeking a sponsor / Auth WG agenda slotPer the PR-based SEP workflow this needs a core-maintainer sponsor to advance Draft → In-Review. The reviewer feedback above is now resolved in-text, and a reference implementation exists, so I'd like to put it in front of the Auth WG. This draft was written specifically to clear the two concerns the Auth WG raised against SEP-1415:
Reference implementation (the §"Reference implementation" deliverable): server-side RFC 9421 verification as an @D-McAdams — since you're shepherding the DPoP profile (#1932) and this is the complementary non-OAuth half of the same PoP story, would you (or another Auth WG maintainer — @aaronpk?) be open to sponsoring, or to a slot on the next Auth WG agenda to discuss? I can present the stateless |
|
Hey, saw the mention, took a read through, and wanted to give some context. I think you'll run into significant questions with this approach. On proof-of-possession: The Auth WG debated this space, including HTTP Message Signatures, and landed on DPoP. The bar for revisiting that decision is high. (The MCP authorization spec is intentionally opinionated. Having two competing PoP mechanisms in the core spec creates implementation burden and ambiguity.) On the broader authentication model: The proposal alludes to a broader topic of whether MCP can support a non-OAuth authentication model, such as with decentralized identity and crypto wallet authentication. The working group has made a deliberate choice to standardize on OAuth. Autonomous agent authentication, including the workload-to-workload cases, is covered by OAuth workload identity federation (SPIFFE, WIMSE, etc.). Overall, a non-OAuth authentication model will face significant resistance in the Auth WG. If there's a community with interest in wallet-native or decentralized-identity MCP flows, another path that doesn't require changing the core spec is MCP's extension model (https://modelcontextprotocol.io/extensions/overview). That's likely a faster and more realistic path for this work. |
|
@D-McAdams thanks for feedback, very helpful. Do you have 15 mins to chat? Will show you specific set of use-cases I (+crypto/wallet) community interested in + demo, and get your take on what best to do to proceed. Email is nprasad@moonpay.com |
|
That's a fair call, and the extension path makes sense to me — thanks for pointing it there rather than just closing the door. I'd like to take you up on it. Reframing this as an Extensions Track proposal (per SEP-2133) rather than a core change actually resolves the two concerns directly: it's opt-in and disabled by default, so there's no second PoP mechanism imposed on the core spec, and it touches nothing in the authorization spec — it negotiates purely via I can satisfy the Extensions-Track bar: there's already a reference implementation in an official SDK — an Two asks, whichever is easiest for you:
I'll rework this PR into Extensions-Track form (identifier, |
Per Auth WG feedback (DPoP is the core PoP mechanism; non-OAuth auth faces resistance in core), repackage this as the opt-in MCP extension `io.modelcontextprotocol/http-message-signatures` rather than a core change: - Type: Standards Track -> Extensions Track; add Extension ID + Working Group. - §3.1: negotiate via `capabilities.extensions` (SEP-2133) instead of a new core `ServerCapabilities.authentication` field; settings object documented; opt-in, disabled by default, graceful fallback to core bearer/OAuth. - §2.6.2: carry `cnf` in the extension settings object, not core `clientInfo`. - §5: "Core schema impact: none" — drop the core schema changes entirely; `signatures/rotateKey` scoped/namespaced to the extension. - Abstract + relationship table: framed as additive, complementary to DPoP (SEP-1932), sibling to OAuth Client Credentials in ext-auth. - New "Extension governance (SEP-2133)" section: identifier, ext-auth home, experimental incubation under the MCP Authorization WG, Apache-2.0, reference impl satisfies the Extensions Track prerequisite. - index + References updated.
|
@njdawn: Thank you very much for the detailed answer.
Yep 😀. I tried to describe the options in a neutral way. But indeed, personally, I prefer a pluggable approach and am also in favor of a decentralisation. |
Summary
Adds a draft SEP proposing RFC 9421 HTTP Message Signatures as an optional, additive proof-of-possession client-authentication mechanism for MCP. It supersedes the dormant SEP-1415 with the technical-feedback fixes from that thread, and is complementary to (not in competition with) SEP-1932 (DPoP).
Why this proposal
MCP currently authenticates clients with bearer tokens (OAuth access tokens, API keys,
MCP-Session-Id). That model has well-known structural weaknesses that the rest of the web has been migrating away from:(@method, @target-uri, content-digest, mcp-protocol-version, mcp-session-id)binds the credential to this specific request.created+noncecollapse that window to single-digit minutes.tagprovides a stable, unforgeable client identifier across key rotations.The acute use case is wallet-based and high-stakes authentication — MCP servers brokering on-chain transactions, payments, secret stores, or production database writes. A leaked bearer in those settings drains a wallet or exfiltrates secrets with no recovery. Proof-of-possession lets the wallet key itself become the natural MCP client credential.
What's different from SEP-1415
The 1415 thread surfaced a series of RFC-compliance issues that this draft addresses explicitly, with citations:
algparameter creates substitution-attack riskkty+crvper RFC 9421 §7.3.5createdlisted as a signed componentcreatedis a signature parameter (§2.2), not a componentAccept-Signatureresponse header (§3.3)(tag, nonce)cache (§2.3)Signature-Agentheader (draft-meunier-http-message-signatures-directory) for first contact (§2.6.1)MCP-Protocol-Versionnot in signaturetagparameter as stable client ID (§2.5);signatures/rotateKeymethod (§3.4)cnfinclientInfofor sessioned,Signature-Agentfor stateless (§2.6)Relationship to in-flight work
Signature-Agent.Status
rmcp; client-side TypeScript fetch wrapper on the official SDK) planned and will be linked once a sponsor advances this toIn-Review.Checklist
cc: potential reviewers from the closed 1415 thread who provided technical feedback: @dickhardt @jricher @dadrus @fsiyavud @spacewander @covia-dev — your input shaped this draft.