hmac-auth
Authenticates requests signed with an HMAC key pair.
hmac-authPriority 2530Needs a Consumer with a hmac-auth CredentialWhat it does
hmac-auth admits a request that the client signed with a secret it shares with the gateway. The secret lives on a consumer, as one of its credentials, under Secret key beside a Key ID. The secret itself is not sent. Each request carries a Date header and an Authorization header that names the keyId, the algorithm, the signed headers and the signature.
A request whose signature the credential checks passes as that consumer and reaches the backend. A request without an Authorization header is answered 401 with client request can't be validated: missing Authorization header. Authentication shows how consumers and credentials fit together.
When to use it
- A partner's billing system signs every request it sends to your orders API, and the secret it signs with never crosses the network.
- Machine-to-machine calls where a fixed key in a header would be too easy to copy from a log or a proxy.
- Each signature should cover the method and path as well, with
@request-targetlisted under Signed headers. - A request body that must reach the backend as the client sent it: Validate request body compares it with the client's
Digestheader.
Not for a fixed API key a client sends as it is — see key-auth (Authenticates consumers with an API key sent in a header or query parameter), a signed token issued once and sent on many requests — see jwt-auth (Authenticates consumers with a JSON Web Token they present) or a username and password — see basic-auth (Authenticates consumers with HTTP Basic credentials).
Set it up
Require signed requests and check the body against its digest
Under Basics fill Allowed algorithms as in the JSON below and fill Signed headers as in the JSON below. Under Behavior set Clock skew to 60 seconds, turn on Validate request body and set Request body limit to 1048576.
{
"allowed_algorithms": [
"hmac-sha256"
],
"signed_headers": [
"date",
"digest",
"@request-target"
],
"clock_skew": 60,
"validate_request_body": true,
"max_req_body_size": 1048576
}
More scenarios
Give a partner a key id and a signing secretcredential
Set Key ID to partner-billing and set Secret key to <secret>.
{
"key_id": "partner-billing",
"secret_key": "<secret>"
}
Things to know
- On a route that signs
dateand@request-target, a request without a signature is answered401. The same request with aDateheader and a signature made with the secret ofpartner-billingis answered200. - Signed headers — Each name must appear, spelled exactly the same, in the client's signed headers list, where @request-target stands for the method and path.
- Signed headers — An empty list is refused when you save.
- Allowed algorithms — Only
hmac-sha1,hmac-sha256andhmac-sha512can be listed;hmac-md5is refused when you save. - Clock skew — However this is set, a request without a Date header the gateway can read as GMT time is refused: the skew cannot be turned off.
- Validate request body — With this on, the client must also send a Digest header of SHA-256= and the base64 body hash, or the request is refused.
- Key ID — A key ID that another credential already carries is refused when you save, whoever it belongs to.
- Anonymous consumer — It takes a consumer's username: letters, digits,
_and-. A name with a dot in it is refused when you save. - Anonymous consumer — While this names an existing consumer, a request with no credential or a wrong one passes as that consumer instead of being refused. A name that belongs to no consumer refuses them with 401.
- Your backend receives the consumer's username in
X-Consumer-Username, the name of the consumer whose secret checked the signature. - AdviceList
@request-targetanddateunder signed headers on every route, so that each signature covers the method, the path and the time it was made.
Settings
The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set.
Basics
allowed_algorithmsarray of stringsdefault ["hmac-sha1","hmac-sha256","hmac-sha512"]signed_headersarray of stringsdefault ["date"]Behavior
clock_skewintegerdefault 300validate_request_bodybooleandefault falseWhen Validate request body is true
max_req_body_sizeintegerdefault 67108864The largest request body in bytes read to check its digest, where a larger one is answered 413.
hide_credentialsbooleandefault falseanonymous_consumerstringpattern
^([$]secret://.+|[$][Ee][Nn][Vv]://.+|[a-zA-Z0-9_-]{1,256})$Advanced
realmstringdefault hmacSent back in the WWW-Authenticate header of a refusal.
pattern
^[ -!#-[\]-~]+$Credential
What each consumer's credential for hmac-auth carries.
key_idstringRequiredThe name the client sends as keyId in its Authorization header, unique across all consumers. A key ID that another credential already carries is refused, whoever it belongs to.
secret_keystringRequiredStored on the engine and shown only to roles that manage this object.