Request Signing
Request signing attaches a cryptographic signature to each HTTP request, proving the caller's identity and binding the signature to the method, path, headers, and body.
Definition
Request signing is a mechanism where the sender computes a cryptographic MAC or digital signature over a canonicalized request, and the receiver recomputes it with a shared secret or public key to authenticate the caller and detect tampering in transit.
Context and scope
Use it for server-to-server APIs, webhooks, and payment callbacks where bearer tokens are too easy to replay or leak, and where the request itself must be protected.
Common misconceptions
- Signing encrypts the payload; it only proves integrity and origin
- Signing the body alone is enough; the method, path, and timestamp must be covered too
- A TLS connection makes signing redundant; TLS ends at the terminator or proxy
Anti-patterns
- Signing only the JSON body and letting headers or query parameters be altered
- Accepting signatures with no timestamp window, allowing indefinite replay
- Building a custom canonicalization format instead of using a standard one
Related concepts
Related examples
Authoritative source
What signing proves
A request signature binds a secret or private key to the exact bytes of a request. The receiver can verify that the caller knew the key and that nobody changed the method, path, headers, or payload. It is an integrity and authentication control, not encryption; observers still see the content unless TLS protects it.
How it works
RFC 9421 defines a canonical form built from selected components. The sender lists them in Signature-Input, for example sig1=("@method" "@path" "content-digest");created=1788307200;keyid="k1", then sends Signature: sig1=:base64value: and a Content-Digest over the body. The receiver rebuilds the same string, verifies the signature with the registered key, checks the creation time against a short window, and optionally records the nonce to block replay.
Common alternatives include HMAC-SHA256 over a sorted parameter string, or asymmetric signatures so the verifier never holds the signing key. Asymmetric signing is preferable when many receivers must verify and none should be able to forge.
When to use it
Sign server-to-server calls that cross trust boundaries, webhook deliveries, and financial instructions. It is also useful when requests pass through proxies or gateways that terminate TLS, because the signature survives beyond the TLS endpoint. For browser clients, signing keys cannot be kept secret, so use short-lived tokens instead.
Trade-offs
Canonicalization is the fragile part: header order, whitespace, duplicate headers, and URL encoding must match exactly on both sides. Signing large bodies forces buffering or streaming digests. Clocks drift, so windows must tolerate skew without enabling replay. Key distribution and rotation add operational work.
Example and misconceptions
A webhook provider signs POST /hooks with a timestamp and content digest. A receiver that checks only the body accepts a replayed request with an altered X-Tenant header. Checking the full component list and the timestamp window rejects it.
The common misconception is that signatures replace TLS. They complement it: TLS protects the channel, while signing protects the request against intermediaries and replay.
Related concepts: Webhooks, Idempotency, and JSON Web Token (JWT).