Configure HMAC Authentication
HMAC authentication provides a high level of security by requiring clients to sign their requests using a shared secret. This helps prevent tampering and replay attacks because the signature is tied to the request target and the request timestamp.
The hmac-auth plugin in API7 Gateway verifies the incoming signature against the configured consumer credential.
Use this guide for the common signing workflow. For the full plugin field reference and advanced options such as signed headers and request body validation, see hmac-auth.
Prerequisites
- An API7 Enterprise instance is running.
- A Gateway Group is created and a Gateway instance is running.
- A token from the Dashboard.
Configure HMAC Authentication
Setting up HMAC authentication involves three steps:
- Create a published service with a valid upstream.
- Create a route that enables
hmac-auth. - Create a consumer and attach an HMAC credential.
Step 1: Create a Published Service with an Upstream
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/services/hmac-auth-httpbin-service?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "hmac-auth-httpbin-service",
"upstream": {
"type": "roundrobin",
"scheme": "http",
"nodes": [
{
"host": "httpbin.org",
"port": 80,
"weight": 100
}
]
}
}'
services:
- name: hmac-auth-httpbin-service
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- name: hmac-auth-route
uris:
- /anything/hmac-auth
methods:
- GET
plugins:
hmac-auth:
clock_skew: 300
allowed_algorithms:
- hmac-sha256
consumers:
- username: hmac-auth-consumer
credentials:
- name: hmac-auth-consumer-cred
type: hmac-auth
config:
key_id: client-1
secret_key: my-hmac-secret
adc sync -f adc.yaml
Step 2: Create a Route and Enable hmac-auth
- Admin API
- ADC
curl -k "https://localhost:7443/apisix/admin/routes/hmac-auth-route?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "hmac-auth-route",
"paths": ["/anything/hmac-auth"],
"methods": ["GET"],
"service_id": "hmac-auth-httpbin-service",
"plugins": {
"hmac-auth": {
"clock_skew": 300,
"allowed_algorithms": ["hmac-sha256"]
}
}
}'
The route is already included in the previous adc.yaml example.
Step 3: Create a Consumer and Credential
- Admin API
- ADC
# 1. Create the consumer
curl -k "https://localhost:7443/apisix/admin/consumers/hmac-auth-consumer?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"username": "hmac-auth-consumer"
}'
# 2. Create the hmac-auth credential
curl -k "https://localhost:7443/apisix/admin/consumers/hmac-auth-consumer/credentials/hmac-auth-consumer-cred?gateway_group_id={group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "hmac-auth-consumer-cred",
"plugins": {
"hmac-auth": {
"key_id": "client-1",
"secret_key": "my-hmac-secret"
}
}
}'
The consumer and credential are already included in the previous adc.yaml example.
Validate the Configuration
First, send a request without the HMAC headers. The gateway should reject it with 401 Unauthorized:
curl -i "http://127.0.0.1:9080/anything/hmac-auth"
Then generate and send a signed request with Python:
import base64
import hashlib
import hmac
import urllib.request
from email.utils import formatdate
key_id = "client-1"
secret_key = b"my-hmac-secret"
request_path = "/anything/hmac-auth"
date_header = formatdate(timeval=None, localtime=False, usegmt=True)
signing_string = f"{key_id}\nGET {request_path}\ndate: {date_header}\n"
signature = base64.b64encode(
hmac.new(secret_key, signing_string.encode(), hashlib.sha256).digest()
).decode()
request = urllib.request.Request(
"http://127.0.0.1:9080/anything/hmac-auth",
headers={
"Date": date_header,
"Authorization": (
f'Signature keyId="{key_id}",algorithm="hmac-sha256",'
f'headers="@request-target date",signature="{signature}"'
),
},
)
with urllib.request.urlopen(request, timeout=20) as response:
print(response.status)
print(response.read().decode())
Run the script:
python3 hmac-request.py
You should receive 200 OK, and the upstream response should include headers similar to the following:
{
"headers": {
"Authorization": "Signature keyId=\"client-1\",algorithm=\"hmac-sha256\",headers=\"@request-target date\",signature=\"<signature>\"",
"Date": "Tue, 21 Apr 2026 09:06:44 GMT",
"X-Consumer-Username": "hmac-auth-consumer",
"X-Credential-Identifier": "hmac-auth-consumer-cred"
}
}
If the authenticated request still returns 401, or the route returns 404, immediately after you apply the configuration, wait a few seconds for the latest configuration to reach the gateway and retry.
Next Steps
- Configure JWT Authentication - use JSON Web Tokens for stateless authentication.
- Configure Key Authentication - use simple API keys for quick security.
- Learn about Consumers and Credentials - understand how API7 Gateway manages identities.