skills/a6-plugin-hmac-auth/SKILL.md
Skill for configuring the Apache APISIX hmac-auth plugin via the a6 CLI. Covers HMAC signature authentication, consumer credential binding with key_id/secret_key, allowed algorithms, clock skew handling, request body validation, signed headers, and common operational patterns.
npx skillsauth add moonming/a6 a6-plugin-hmac-authInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| allowed_algorithms | array | No | ["hmac-sha1","hmac-sha256","hmac-sha512"] | HMAC algorithms allowed |
| clock_skew | integer | No | 300 | Max allowed time difference in seconds between client and server |
| signed_headers | array | No | — | Additional headers required in the HMAC signature |
| validate_request_body | boolean | No | false | Validate request body integrity via SHA-256 digest |
| hide_credentials | boolean | No | false | Remove Authorization header before forwarding upstream |
| anonymous_consumer | string | No | — | Consumer username for unauthenticated requests |
| realm | string | No | "hmac" | Realm in WWW-Authenticate response header |
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| key_id | string | Yes | Unique identifier for the consumer |
| secret_key | string | Yes | Secret key for HMAC computation. Auto-encrypted in etcd. |
a6 consumer create -f - <<'EOF'
{
"username": "alice"
}
EOF
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"
}
}
}'
a6 route create -f - <<'EOF'
{
"id": "hmac-protected",
"uri": "/api/*",
"plugins": {
"hmac-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF
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>"'
Signature keyId="{key_id}",algorithm="{algorithm}",headers="{signed_headers}",signature="{signature}"
| Component | Description |
|-----------|-------------|
| keyId | Consumer's key_id value |
| algorithm | One of: hmac-sha1, hmac-sha256, hmac-sha512 |
| headers | Space-separated list: @request-target date [additional...] |
| signature | Base64-encoded HMAC signature |
The signing string is newline-separated:
{key_id}\n
{METHOD} {path}\n
date: {Date header value}\n
{additional-header}: {value}\n
key_id\n{
"plugins": {
"hmac-auth": {
"allowed_algorithms": ["hmac-sha256", "hmac-sha512"]
}
}
}
{
"plugins": {
"hmac-auth": {
"clock_skew": 600
}
}
}
Allows up to 10 minutes time difference.
{
"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.
{
"plugins": {
"hmac-auth": {
"signed_headers": ["x-custom-header-a", "x-custom-header-b"]
}
}
}
| Header | Value |
|--------|-------|
| X-Consumer-Username | Consumer's username |
| X-Credential-Identifier | Credential ID |
| X-Consumer-Custom-Id | Consumer's labels.custom_id (if set) |
| Symptom | Cause | Fix |
|---------|-------|-----|
| 401 signature mismatch | Signing string differs from server expectation | Verify newline format, header lowercase, key_id first line |
| 401 clock skew | Date header too far from server time | Sync clocks or increase clock_skew |
| 401 algorithm not allowed | Client used algorithm not in allowed_algorithms | Add algorithm to allow list or change client |
| 401 body digest mismatch | Body changed after digest computed | Recompute Digest header from actual body |
| Signature hard to debug | Complex signing string | Log the exact signing string client-side and compare |
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 syncmanages the consumer resource but credentials are sub-resources.
tools
Core skill for working with the a6 CLI — the Apache APISIX command-line tool. Provides project conventions, command patterns, architecture overview, and development workflow. Load this skill when working on a6 source code, adding new commands, writing tests, or modifying any a6 component.
tools
Recipe skill for implementing multi-tenant API gateway patterns using the a6 CLI. Covers tenant isolation via Consumer Groups, host/path/header-based routing, per-tenant rate limiting, context forwarding with proxy-rewrite, and declarative config sync workflows for multi-tenant management.
tools
Recipe skill for configuring mutual TLS (mTLS) using the a6 CLI. Covers SSL certificate management, upstream mTLS to backend services, client certificate verification, and end-to-end mTLS setup from client through APISIX to upstream.
tools
Recipe skill for configuring upstream health checks using the a6 CLI. Covers active health checks (HTTP probing), passive health checks (response analysis), combining both, configuring healthy/unhealthy thresholds, and monitoring upstream node status.