Conversation
Context / Closes #135. Defines a layered signature architecture: SHARED FOUNDATION ├── Canonicalization: JCS (RFC 8785) ├── Algorithms: ES256 (required), ES384, ES512 ├── Key Format: JWK (RFC 7517) ├── Key Discovery: signing_keys[] in /.well-known/ucp └── Replay Protection: idempotency-key (business layer) │ ├── REST BINDING (RFC 9421) │ Headers: Signature, Signature-Input, UCP-Content-Digest-JCS │ └── MCP BINDING (RFC 7515 Appendix F) Fields: meta.signature, meta.idempotency-key, meta.ucp-agent JCS canonicalization (RFC 8785): - Deterministic JSON serialization before signing - Avoids whitespace/key-ordering verification failures - Custom header `UCP-Content-Digest-JCS` (not RFC 9530 Content-Digest) because we hash canonicalized JSON, not raw bytes Transport-specific formats: - REST uses RFC 9421 HTTP Message Signatures (modern standard) - MCP uses detached JWS (RFC 7515 Appendix F) in meta.signature - Both sign the full message; MCP excludes only meta.signature field Changes to OpenAPI: - `Request-Signature` header → `Signature` + `Signature-Input` headers - `X-Detached-JWT` response header → `Signature` + `Signature-Input` - `UCP-Content-Digest-JCS` header for body digest Other updates: - checkout-rest.md, checkout-mcp.md: Added Message Signing sections - order.md: Rewrote webhook signing to use RFC 9421 - ap2-mandates.md: Now references signatures.md for crypto primitives - openrpc.json: Added signature field to meta, added meta to cart methods - mkdocs.yml: Added signatures.md to nav and llmstxt sections
drewolson-google
left a comment
There was a problem hiding this comment.
Generally looks very good to me. I've included a few small comments.
- Separate "Implementation requirements" (MUST verify ES256) from
"Usage guidance" (SHOULD use ES256 for compatibility)
- Removed "Signers: use newest key" - no way to determine key age
from JWK spec, and verifiers accept any key in signing_keys[]
|
A couple of key takeaways from today's working group call... 1. Do we really need request signatures?Yes and no.
Recommendation: "Businesses SHOULD authenticate agents". The spec should allow multiple mechanisms (API keys, signatures, MTLS) without mandating a single approach. Signatures become valuable when you want permissionless agent onboarding, and we should spec this path. 2. If agent auth is the primary goal, can we simplify what we're signing?Likely, yes. Current proposal signs the entire request body with JCS canonicalization, which is complex and might be unnecessary — see 3. We could, potentially, skip signing body or consider As a next step, we'll tap security folks to review and help converge on a recommendation. 3. Bonus: can we unify on RFC 9421?Likely, yes. UCP's MCP transport runs over HTTP, which means we can rely on 9421: single signature mechanism, CDN/edge can validate, no JCS needed. This would be a significant simplification. |
This restructures UCP's signature specification based on working group discussion. Key changes: Multiple authentication mechanisms: - HTTP Message Signatures, API keys, OAuth 2.0, mTLS, choose whichever - Businesses choose what fits their security model and integration patterns - Implementations SHOULD maintain allowlists of trusted profiles RFC 9421 for all HTTP transports: - REST and MCP (streamable HTTP) now use the same signing mechanism - Signature + Signature-Input headers replace the deprecated Request-Signature - Covered components: @method, @path, content-digest, ucp-agent, idempotency-key Content-Digest (raw bytes) replaces JCS canonicalization: - Request signatures hash raw body bytes per RFC 9530 - Simpler implementation, no JSON canonicalization complexity - JCS retained only for AP2 mandates
|
@ACSchil fyi, updated to capture shape we discussed yesterday, ptal. |
Context / Closes #135. Defines a layered signature architecture:
JCS canonicalization (RFC 8785):
UCP-Content-Digest-JCS(not RFC 9530 Content-Digest)because we hash canonicalized JSON, not raw bytes
Transport-specific formats:
Changes to OpenAPI:
Request-Signatureheader →Signature+Signature-InputheadersX-Detached-JWTresponse header →Signature+Signature-InputUCP-Content-Digest-JCSheader for body digestOther updates:
Checklist