Skip to main content

a6-plugin-hmac-auth

Overview

The hmac-auth plugin authenticates requests using HMAC (Hash-based Message Authentication Code) signatures. Clients compute an HMAC signature over the request method, path, date, and optional headers/body, then include it in the Authorization header. APISIX recomputes the signature server-side and verifies it matches. This provides request integrity verification without transmitting secrets over the wire.

When to Use

  • Request integrity verification (tamper-proof API calls)
  • Server-to-server authentication where both sides share a secret
  • APIs requiring body integrity validation
  • Environments where tokens or passwords should never appear in requests

Plugin Configuration Reference (Route/Service)

FieldTypeRequiredDefaultDescription
allowed_algorithmsarrayNo["hmac-sha1","hmac-sha256","hmac-sha512"]HMAC algorithms allowed
clock_skewintegerNo300Max allowed time difference in seconds between client and server
signed_headersarrayNoAdditional headers required in the HMAC signature
validate_request_bodybooleanNofalseValidate request body integrity via SHA-256 digest
hide_credentialsbooleanNofalseRemove Authorization header before forwarding upstream
anonymous_consumerstringNoConsumer username for unauthenticated requests
realmstringNo"hmac"Realm in WWW-Authenticate response header

Consumer Credential Reference

FieldTypeRequiredDescription
key_idstringYesUnique identifier for the consumer
secret_keystringYesSecret key for HMAC computation. Auto-encrypted in etcd.

Step-by-Step: Enable hmac-auth on a Route

1. Create a consumer

a6 consumer create -f - <<'EOF'
{
"username": "alice"
}
EOF

2. Add hmac-auth credential

curl "$(a6 context current -o json | jq -r .server)/apisix/admin/consumers/alice/credentials" \
-X PUT \
-H "X-API-KEY: $(a6 context current -o json | jq -r .api_key)" \
-d '{
"id": "cred-alice-hmac",
"plugins": {
"hmac-auth": {
"key_id": "alice-key",
"secret_key": "alice-secret-key-value"
}
}
}'

3. Create a route with hmac-auth enabled

a6 route create -f - <<'EOF'
{
"id": "hmac-protected",
"uri": "/api/*",
"plugins": {
"hmac-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF

4. Generate signature and test

The HMAC signature follows the HTTP Signatures draft.

Python example:

import hmac, hashlib, base64
from datetime import datetime, timezone

key_id = "alice-key"
secret_key = b"alice-secret-key-value"
method = "GET"
path = "/api/users"
algorithm = "hmac-sha256"

gmt_time = datetime.now(timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT')

signing_string = f"{key_id}\n{method} {path}\ndate: {gmt_time}\n"

signature = base64.b64encode(
hmac.new(secret_key, signing_string.encode(), hashlib.sha256).digest()
).decode()

# Use these headers in request:
# Date: {gmt_time}
# Authorization: Signature keyId="{key_id}",algorithm="{algorithm}",
# headers="@request-target date",signature="{signature}"

curl example:

curl -i http://127.0.0.1:9080/api/users \
-H "Date: $(date -u +'%a, %d %b %Y %H:%M:%S GMT')" \
-H 'Authorization: Signature keyId="alice-key",algorithm="hmac-sha256",headers="@request-target date",signature="<computed_signature>"'

Authorization Header Format

Signature keyId="{key_id}",algorithm="{algorithm}",headers="{signed_headers}",signature="{signature}"
ComponentDescription
keyIdConsumer's key_id value
algorithmOne of: hmac-sha1, hmac-sha256, hmac-sha512
headersSpace-separated list: @request-target date [additional...]
signatureBase64-encoded HMAC signature

Signing String Construction

The signing string is newline-separated:

{key_id}\n
{METHOD} {path}\n
date: {Date header value}\n
{additional-header}: {value}\n
  • First line: the key_id
  • Second line: HTTP method + space + request path
  • Subsequent lines: lowercase header names with values
  • Each line terminated with \n

Common Patterns

Restrict to specific algorithms

{
"plugins": {
"hmac-auth": {
"allowed_algorithms": ["hmac-sha256", "hmac-sha512"]
}
}
}

Increase clock skew tolerance

{
"plugins": {
"hmac-auth": {
"clock_skew": 600
}
}
}

Allows up to 10 minutes time difference.

Validate request body

{
"plugins": {
"hmac-auth": {
"validate_request_body": true
}
}
}

Client must include Digest: SHA-256={base64_sha256_of_body} header. APISIX recomputes the body digest and rejects the request if it does not match.

Require custom headers in signature

{
"plugins": {
"hmac-auth": {
"signed_headers": ["x-custom-header-a", "x-custom-header-b"]
}
}
}

Headers Added to Upstream

HeaderValue
X-Consumer-UsernameConsumer's username
X-Credential-IdentifierCredential ID
X-Consumer-Custom-IdConsumer's labels.custom_id (if set)

Troubleshooting

SymptomCauseFix
401 signature mismatchSigning string differs from server expectationVerify newline format, header lowercase, key_id first line
401 clock skewDate header too far from server timeSync clocks or increase clock_skew
401 algorithm not allowedClient used algorithm not in allowed_algorithmsAdd algorithm to allow list or change client
401 body digest mismatchBody changed after digest computedRecompute Digest header from actual body
Signature hard to debugComplex signing stringLog the exact signing string client-side and compare

Config Sync Example

version: "1"
consumers:
- username: alice
routes:
- id: hmac-protected
uri: /api/*
plugins:
hmac-auth: {}
upstream_id: my-upstream
upstreams:
- id: my-upstream
type: roundrobin
nodes:
"backend:8080": 1

Note: Consumer credentials (key_id/secret_key) must be created separately via the Admin API; a6 config sync manages the consumer resource but credentials are sub-resources.


This page is generated from a6-plugin-hmac-auth/SKILL.md in the api7/a6 repository. Browse all skills on the AI Agent Skills page.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation