POST /mcp must be signed. Unsigned, expired, replayed, or wrongly keyed
requests never reach a tool. GET /.well-known/fau-node is not signed.
Covered components
Always cover:@method@target-uri(full public URL, including scheme — e.g.https://n….relay.fau.run/mcp)@authority(hostname only)content-digest
Signature parameters
Default lifetime in the reference signer is 120 s (still ≤ 300).
Content-Digest
SHA-256 of the raw body bytes, RFC 9530 form with standard Base64 (not base64url):Example headers
Label issig1 in the reference implementation:
Signature / digest use standard Base64 with surrounding colons. Key documents and
queue envelopes use base64url.
Pseudocode
node/src/fedagent/crypto/signatures.py (sign_request).
Rules that bite
- Agent domain must contain at least one dot (e.g.
assistant.example), and must not equal the node hostname. - Sign the public URL you will send on the wire. Redirects break signatures —
call
/mcp(or/mcp/) directly; do not follow 3xx. - Body larger than 256 KiB → HTTP
413 {"error":"payload_too_large"}. - Missing/bad signature → HTTP
401 {"error":"signature_invalid",…}(not JSON-RPC).