Apache APISIX HMAC request signing with hmac-auth

HMAC request signing with the APISIX hmac-auth plugin lets partners and machine clients prove each request with a shared secret. This page covers how to design, configure, verify and migrate it.

On this page

When HMAC request signing with hmac-auth fits your APIs

HMAC request signing fits when machine clients or partner systems must prove that each request came from a holder of a shared secret and that the request was not altered in transit, with no human user signing in. Typical cases are server-to-server integrations, batch jobs, and partner systems that send payment, order or event data and need evidence that the body and key request details were not changed. The hmac-auth plugin in Apache APISIX checks the signature computed over a signing string, requires a Date header by default, allows 300 seconds of clock skew, and can validate a SHA-256 body Digest. Each client is identified by a key_id sent as keyId, which maps the request to a consumer. The plugin supports hmac-sha1, hmac-sha256 and hmac-sha512. Confirm with your security team which algorithm your partners can implement before you choose one, because the signing library on the client side is often the constraint.

Compare this with the alternatives before committing. A static API key with key-auth proves who is calling but does not prove the request content was untouched, and the key is replayed if captured. A JWT from jwt-auth suits callers that already obtain tokens from your identity provider and need claims, but it adds a token issuance flow that a machine client may not need. HMAC is a better fit when integrity of each request matters, when clients can sign locally, and when you can distribute and rotate a secret per consumer. It is a weaker fit when clients are browsers or mobile apps that cannot protect a secret, and when you need user identity or delegated scopes. The plugin was rewritten in APISIX 3.11.0, and the credential field changed from access_key to key_id from that version on, so any existing configuration or client code written against earlier releases needs review before you plan the rollout.

Configuration options and when each one fits

This table compares the hmac-auth settings that shape a signing scheme and shows which suit a partner integration and which suit an internal service. Read each row as a decision: the default is the starting point, and the right-hand column tells you when to change it. Confirm every value against the plugin schema for your APISIX version before you rely on it.

SettingWhat it controlsPartner integrationInternal service
algorithm (hmac-sha1, hmac-sha256, hmac-sha512)The HMAC hash used to sign the request. The plugin accepts all three.Prefer hmac-sha256 or hmac-sha512 and agree the choice in writing with the partner's engineers. Avoid choosing sha1 for new contracts.Use hmac-sha256 unless your clients already standardize on another accepted algorithm. Keep it consistent across services.
signed_headersWhich request headers are included in the signing string. Version 3.17.0 changed the default to date.Keep the default date or add the headers the partner must sign, such as host or content type. Document the exact list in the integration guide.Add headers that carry routing or identity meaning inside your network. Every added header must be sent unchanged by every internal hop.
Date header and clock skewThe plugin requires the Date header by default and allows 300 seconds of clock skew. Requests outside that window are rejected.Confirm that partner systems sync time with NTP. Ask partners in another time zone to test with real request timestamps before go-live.Verify clock sync on all calling hosts, including containers and batch workers. Skew problems often appear only after a node restart.
Body digest validation (SHA-256 Digest)Checks that the request body was not altered in transit by comparing a SHA-256 digest of the body.Turn on for payment, record or write endpoints where body tampering matters. Expect partners to compute the digest on the exact bytes they send.Enable for sensitive internal writes. Skip it on large streaming uploads where buffering the body adds latency and memory cost.
key_id (consumer credential)The identifier the client sends as keyId. It maps the request to a consumer and its secret. Version 3.11 and later use key_id where earlier releases used access_key.Issue one consumer per partner application. Rotate secrets with a second key_id during overlap so the partner can switch without downtime.Issue one consumer per calling service so you can revoke a single workload. Store secrets in your secrets manager, not in configuration files.
keyId request parameterThe header or field the client uses to name the key_id it signs with. Clients must send it exactly as the plugin expects.Include a sample signed request and expected response codes in the partner onboarding pack. Ask the partner to confirm the parameter name against your schema version.Standardize the client library so every service sends the same parameter form. Test each service once after upgrading APISIX.
Plugin version and schemaField names and defaults changed across releases, including the 3.11 rewrite and the 3.17.0 default change.Pin the APISIX version in the partner agreement and state which schema you support. Notify partners before upgrading past a schema change.Read the schema for your running version and the changelog entries between your version and the target before any upgrade.
Migration from the pre-3.11 pluginReplaces access_key with key_id and changes the signing behavior of the rewritten plugin.Plan a dual-running window with the partner, and confirm which version each side signs against before cutover.Migrate consumer by consumer, run both credential sets in staging, and keep a tested rollback route until all callers are verified.

Setting up hmac-auth on a route

This sequence takes a partner or machine client from an agreed signing contract to a route that accepts only correctly signed requests. Each step closes with a check, so the team knows the gateway behaves as designed before any client goes live.

  1. Agree the signing contract with each client

    Before any configuration, the API owner and each client team agree on the algorithm (hmac-sha1, hmac-sha256 or hmac-sha512), the exact headers included in the signing string, whether the Date header is used, how the body digest is computed, and the clock tolerance both sides will tolerate. Write these decisions into a short specification per client. Done when both teams sign the same example request and get identical signatures from their own tooling.

  2. Create consumers with key_id and secret

    Using the Admin API or your configuration-as-code tooling, create one consumer per client application or partner, and attach an hmac-auth credential containing a unique key_id and a secret. Use the key_id name from the current plugin documentation, since the field was renamed from access_key for APISIX 3.11 and later. Store the secret in your secrets manager, not in the repository. Done when each consumer returns its credential on read and the key_id values are unique across consumers.

  3. Attach hmac-auth to the target routes

    Enable the hmac-auth plugin on the specific routes or services that need it, with the algorithm and signed header settings agreed in step one. Confirm the signed_headers default for your release, because the plugin's default behavior changed in 3.17.0, and set it explicitly so the contract does not depend on a default. Keep unauthenticated routes separate. Done when the route configuration is saved, and a request with no Authorization header is rejected at the gateway.

  4. Define signed headers and body digest rules

    Decide which headers beyond Date must be covered by the signature, and whether the request body must match a SHA-256 Digest header. Signing the body prevents an attacker from reusing a valid signature with altered content. Enable digest validation on routes that accept writes, and document the rule for GET requests with no body. Done when a signed request with a correct Digest passes, and the same request with an edited body fails.

  5. Verify clock skew and expiry behavior

    Confirm the clock tolerance on the gateway matches the agreed contract, which defaults to 300 seconds of skew in the plugin documentation. Synchronize time on gateway nodes and client systems, since drift on either side produces failures that look like signature errors. Send a request with a Date value outside the window. Done when a request inside the window passes and a request outside it is rejected with the expected status.

  6. Test valid, tampered and replayed requests

    Run a test set against a non-production route: a valid signed request, a request with an altered path or query, a request with a changed body, a request signed with a wrong secret, a request with an expired Date, and a replay of a captured valid request inside the window. Record the response for each case. Note that the plugin validates signatures and time windows, so replay within the skew window needs an additional control if your risk model requires one; confirm this with your security team. Done when every case returns the expected result and the results are kept as evidence.

  7. Roll out per client and monitor rejections

    Enable each client on production traffic one at a time, starting with a client whose team has passed the test set. Watch gateway logs for authentication failures, and compare them with client-side signing errors. Keep a documented rollback that removes the plugin from the route or disables the affected consumer. Done when each client sends production traffic with an expected failure rate, and the rollback steps have been checked in a non-production environment.

Security risks in HMAC signing and how to contain them

HMAC signing proves a request came from a holder of the shared secret, but the secret, the signed content and the transport all decide whether that proof holds. The cards below cover where HMAC deployments usually fail and what to check in your APISIX configuration, your logging and your network path before partner or machine traffic goes live.

Secret storage and rotation

The shared secret is the whole trust decision, so anyone who reads the consumer configuration can call the API as that client. Keep secrets out of version control and out of plain Admin API exports where your tooling allows it, and plan rotation as a routine task. Confirm how your APISIX deployment stores consumer credentials, who can read them through the Admin API, and how you will issue a new secret to a partner while the old one is still accepted for a defined overlap.

Replay window from clock skew

A captured signed request stays valid for as long as the allowed skew, so a 300-second window gives an attacker that long to replay it. Replay is most damaging on non-idempotent methods such as payment or transfer calls. Decide whether the skew should be tighter for your partners, and confirm with your team how your upstream handles duplicate requests. Keeping server clocks synchronized is part of the control, because drift consumes the same window.

Signed query strings and headers

Any component the signature does not cover can be changed in transit or by an intermediary without breaking verification. Sign the method, path, query string and the headers that carry business meaning, not only the Date header. Proxies, load balancers and CDNs may rewrite or add headers, so test the full path your traffic takes. Confirm that the signed header list in your client matches what APISIX verifies after any header normalization in front of it.

Body digest validation

Without a body digest, an attacker who captures a valid signature can pair it with a different payload if the signed portion does not cover the body. Enable the SHA-256 Digest check for requests that carry data, and make sure the client computes the digest over the exact bytes sent. Confirm that no proxy re-encodes or compresses the body after signing, because a single changed byte fails verification and can look like an attack in your logs.

TLS as a complement

HMAC does not encrypt the request, so the body, query string and headers are readable by anyone on the path without TLS. TLS protects confidentiality and resists tampering in transit, while the signature proves the client holds the secret. Use TLS on every listener that accepts signed traffic, and treat a plain HTTP path to the gateway as an exposure even when signatures validate. Verify certificate handling in the client and in APISIX separately.

Logs that exclude secrets

Access logs, debug output and error traces can capture the Authorization header, the signature inputs or the secret itself, and those stores are often less protected than the gateway. Review which fields your log format records and what debug logging exposes in a test environment. Confirm that log access is restricted, retention matches your policy, and that signature failures are logged with the key_id and reason rather than the secret.

Migrating consumers from the pre-3.11 hmac-auth plugin

The credential field changed name in APISIX 3.11. Before 3.11, the hmac-auth consumer was configured with an access_key field. From 3.11 and later, the equivalent value is key_id, and clients send it as keyId. The APISIX Ingress Controller 2.0 upgrade guide records this rename, and the rewrite also changed how the plugin behaves, so a consumer that validated under the old plugin is not guaranteed to validate under the new one without review. Before you change anything, inventory every consumer, the APISIX version each gateway runs, and every Ingress Controller resource that carries an hmac-auth credential. Confirm the exact field names and default values against the APISIX hmac-auth plugin documentation for your target version rather than relying on memory of the old behavior.

Run old and new consumers side by side during the transition. A practical pattern is to keep the existing consumer and its access_key credential active while you add a second consumer for the same partner or service with a key_id credential, issued as a new secret. Coordinate with each client team on a cutover window, switch their signing configuration to the new key, and confirm successful calls in gateway logs before you remove the old consumer. Keep the old credential revocable for the whole window, and record which routes each consumer may call so that a rollback re-enables a known state. Rollback should mean re-pointing clients to the old key and restoring the previous gateway configuration, not editing live consumers under pressure.

Review the APISIX CHANGELOG for every release between your current version and your target. The 3.11.0 entry covers the rewrite, and the 3.17.0 entry covers the change that defaults signed_headers to date, which can break signatures that previously covered other headers. Confirm whether your clients sign headers beyond Date and whether they send a body digest. Then test the full signing path in a non-production environment with a representative request set, including clock-skew edge cases, before scheduling production cutover.

Limits to confirm before you commit to hmac-auth

hmac-auth behavior has changed across APISIX releases, and several defaults can be overridden per route. The cards below list the points to confirm against your exact APISIX version and your client libraries before you commit to a signing design.

Supported algorithms for your version

The plugin documentation lists hmac-sha1, hmac-sha256 and hmac-sha512. Confirm which of these your APISIX version accepts and which your partners' client libraries can produce. Do not accept a weaker algorithm than your policy requires just because a client library defaults to it. Record the chosen algorithm per consumer so that rotation later does not silently change what is accepted.

Overridden signed_headers behavior

APISIX 3.17.0 defaulted signed_headers to date, but the value is configurable per route. Test what happens when a route lists fewer headers, adds headers such as Host or a custom request ID, or omits Date. A signature that covers too little can be replayed with altered content, so confirm that the header set you require is enforced on every route that uses this plugin.

Digest handling for non-JSON and streamed bodies

Body digest validation uses a SHA-256 Digest header. Confirm how your APISIX version reads the body for multipart uploads, binary payloads and chunked or streamed requests, and whether the body can be read twice without buffering problems. Check the size of request bodies you expect, because large uploads change memory use at the gateway.

Interaction with other auth plugins

Confirm how hmac-auth behaves when it is combined with key-auth, jwt-auth, multi-auth or consumer restrictions on the same route. Test which plugin decides the consumer, whether a request can satisfy one scheme while carrying another, and what error code a rejected signature returns. Plugin order and consumer identity should be verified with negative tests, not assumed from the docs.

Canonical string from client libraries

Signature failures most often come from the canonical string, not the key. Check how each partner library orders headers, formats the Date value, lowercases header names, encodes the request path and query, and computes the body digest. Ask partners for a reference signing example, then reproduce it against a test route before go-live.

Key migration from access_key to key_id

APISIX 3.11.0 rewrote the plugin, and the APISIX Ingress Controller upgrade guide notes that the required access_key field became key_id for APISIX 3.11 and later. Confirm which field name your gateway and any ingress manifests expect, and plan a dual-running window if older clients still send the previous credential format.

Questions buyers ask about hmac-auth implementation

What drives the cost of implementing hmac-auth?

The cost follows the number of signing relationships and how much each one differs from the others. Each partner or machine client needs its own consumer, key_id and secret, a signing contract that both sides implement the same way, and tests against its actual client code. The main cost drivers are the number of partners, whether they all sign requests the same way or each needs exceptions (different signed headers, body digest handling or algorithms), and whether older clients must keep working during a migration. Ongoing costs are rotation of secrets, onboarding new partners and handling changes to the signing contract. Ask any quote to separate one-time build work from recurring support, and to list each partner as a line item with its client language and test plan.

How long does an hmac-auth rollout take?

Duration depends mainly on how many partner clients must be tested and how many signing variants exist. The gateway configuration for one route is usually the smaller part of the work; the longer parts are agreeing the canonical string with each partner, testing clock skew and body digest behavior against their real clients, and running old and new paths side by side if you are migrating. Timelines should be stated in the written scope, which is agreed before work starts. Ask for the schedule to show partner testing windows and a cutover date that depends on each partner's readiness, not only on your gateway change.

What does the migration from the pre-3.11 hmac-auth plugin involve?

Migration matters because APISIX 3.11.0 rewrote the hmac-auth plugin, and the required consumer field changed from access_key to key_id for APISIX 3.11 and later. Consumer records, Admin API or Ingress Controller configuration and any tooling that creates credentials must be updated together. The APISIX Ingress Controller 2.0 upgrade guide documents this change. Effort increases if your credential lifecycle is automated, if several gateways or Ingress Controller versions run at once, or if partners cannot change their client's keyId value at the same time. Confirm the exact behavior for your APISIX and Ingress Controller versions in the upgrade guide before planning.

What must our client teams provide?

Each partner or internal client team must provide the language and library they use to sign requests, a sample of a signed request and response, the headers they sign, how they format the Date header, and how they compute any body Digest. They also need a test environment and a named contact who can change the client when the signing contract changes. Without these inputs, the gateway team tends to guess the canonical string, which is the most common source of failed rollouts. Ask each partner to confirm the algorithm (hmac-sha1, hmac-sha256 or hmac-sha512) in writing before the build starts.

What must our platform team provide?

Your platform team must provide the APISIX environment (traditional, decoupled or standalone deployment), access to the Admin API or configuration repository, a secret storage approach for consumer secrets, and a decision on who owns credential issuance and rotation. The team also needs logging and monitoring that show signature failures without exposing secrets, and an agreed rollback plan. Clock synchronization across gateways and clients is a platform responsibility, because the 300 seconds of allowed clock skew only works when both sides keep accurate time. Confirm these prerequisites before scheduling partner tests.

Can our internal team implement hmac-auth on its own?

Yes, a capable internal team can implement hmac-auth without a partner, especially with one or two clients and a single APISIX version. The work is a plugin configuration, consumer records and client-side signing that matches the documented canonical string. Teams usually need outside help when they have many partners with different signing libraries, a migration from the older plugin, or no one with time to run cross-party tests. Whichever route you choose, the test plan should include clock skew, a bad digest, an unsupported algorithm and a replayed or expired Date, and each should be checked against your real clients.

What usually goes wrong in hmac-auth testing across clients?

Most failures come from small differences in how clients build the signing string. Common problems include a Date header that is reformatted by a proxy, a body that is modified after the digest is calculated, a client that signs headers the gateway does not expect, and clocks that drift beyond the 300 seconds of allowed skew. Because signed_headers defaults to date from APISIX 3.17.0, clients that sign additional headers need explicit configuration on both sides. Test each client with recorded requests, including requests that intentionally fail, so denials are as well understood as successes.

Does hmac-auth need extra security review before go-live?

Yes, because hmac-auth secrets authenticate machine traffic and a leaked secret lets an attacker sign valid requests. Review how secrets are generated, stored and rotated, which algorithms are allowed (hmac-sha256 or hmac-sha512 are common choices, but confirm your partners support them), and whether body digests are required for write operations. Check that the gateway does not log signatures or secrets. If your compliance program requires evidence of these controls, ask the engagement to prepare the configuration, logs and test records that an independent assessor would review. DeployOpen prepares that evidence; it does not issue audit reports or certifications.

How DeployOpen scopes and delivers hmac-auth work

DeployOpen plans, implements, tests, documents and supports self-hosted open-source platforms inside your own infrastructure, including Apache APISIX gateways. For HMAC request signing, we start from the partner and machine clients you need to serve, then agree the signing design in writing before any configuration changes.

How we scope

  • We inventory each partner and machine client, its signing library and the algorithm it can produce.
  • The written scope lists which routes use hmac-auth, the signed headers, and the body digest rules.
  • We agree the clock skew window and the Date handling with your team before any route is changed.
  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.

How we build

  • We configure hmac-auth consumers with key_id values and secrets stored outside plain route configuration.
  • We confirm the APISIX version in your environment, since the plugin changed in 3.11 and defaults changed in 3.17.
  • We test valid signatures, expired Dates, altered bodies and wrong algorithms against each route.
  • Where a legacy access_key client exists, we plan the credential migration and a parallel run window.

How we hand over

  • You receive the signing specification, consumer inventory and a reference client example for each partner.
  • Runbooks cover key rotation, adding consumers, and diagnosing clock skew or digest failures.
  • Test cases and results are documented so your team can repeat the denial and acceptance checks.
  • Configuration is delivered as files in your repository, so changes can be reviewed and reverted.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • Support can cover APISIX upgrades that touch the hmac-auth plugin or its defaults.
  • We can rerun the signing tests after client library changes or new partner onboarding.
  • Your team keeps ownership of the gateway, its keys and its infrastructure throughout.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.