> ## Documentation Index
> Fetch the complete documentation index at: https://auth0.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure HTTP Message Signatures in Tenant ACLs

> Learn how to use HTTP Message Signatures with Tenant ACLs to block requests that don't originate from your trusted edge proxy or API gateway.

This feature is only available for Enterprise plan customers. To learn more, read [Pricing](https://auth0.com/pricing).

Auth0 Tenant Network Access Control Lists (ACLs) allow enterprise tenants to evaluate and enforce cryptographic origin validation on incoming HTTP traffic using [RFC 9421 HTTP Message Signatures (HMAC-SHA256)](https://www.rfc-editor.org/rfc/rfc9421).

By inspecting request signatures directly at the Auth0 network boundary, you can ensure traffic originates exclusively from trusted edge proxies or API gateways, to prevent request spoofing, parameter tampering, and direct tenant bypass.

## Use case and security challenge

When hosting authentication flows, organizations frequently deploy reverse proxies or edge gateways (such as Cloudflare Workers, Kong, or Envoy) downstream of Auth0 to enforce custom security policies, IP filtering, or header enrichment.

If an attacker discovers your Auth0 tenant domain (e.g., `https://YOUR_AUTH0_DOMAIN.com`), they can send requests directly to core authentication endpoints like `/oauth/token` or `/authorize` and bypass your edge security checks. Standard static API keys in custom headers are vulnerable to interception or leakage.

## How it works

When you enforce HTTP Message Signatures in Tenant ACLs:

1. Your edge proxy computes an HMAC-SHA256 cryptographic signature covering critical HTTP attributes (such as `@method`, `@path`, and raw `@query-param` key-value pairs) along with required metadata (`created`, `expires`, and `keyid`).
2. As traffic hits Auth0, Tenant ACLs verify the HMAC signature and timestamp parameters before processing the request.
3. Auth0 immediately blocks direct, unsigned, tampered, or expired requests at the network layer.

### Signature evaluation criteria

Auth0 checks signatures for the following:

* The algorithm must be HMAC-SHA256 (`hmac-sha256`).
* The signature can cover the following derived HTTP request components:

| **HTTP Message Components** | **Description** |
| - | - |
| `@method` | Verifies the HTTP request method (e.g., `POST`, `GET`) |
| `@path` | Verifies the target path (excluding query parameters) |
| `@query-param` | Verifies specific named query parameters and values (e.g., `"@query-param";name="state"`), tying signatures to specific authorization requests for enhanced replay protection |

* Every signature input string must include `created`, `expires`, and `keyid` parameters. Requests missing any of these parameters are treated as non-matching.
* The signature window can be at most 1 hour (`expires - created <= 3600`), and Auth0 applies a built-in 60-second clock skew tolerance (`created <= now + 60s` and `now <= expires + 60s`).
* Requests containing multiple signature dictionary labels are rejected.

## Configure

### Register edge proxy signing key

Create an HMAC-SHA256 key to sign HTTP requests from your edge proxy.

```http theme={null}
POST /api/v2/keys/network-acls
Content-Type: application/json
Authorization: Bearer {YOUR_MANAGEMENT_API_TOKEN}

{
  "name": "edge-proxy-signing-key-v1",
  "alg": "hmac-sha256",
  "value": "KEY_VALUE"
}
```

The `value` field must be a Base64-encoded string that decodes to a minimum of 32 raw bytes and a maximum of 512 bytes.

Sample response

```json theme={null}
{
  "id": "key_aBcDeFgH",
  "name": "edge-proxy-signing-key-v1",
  "alg": "hmac-sha256",
  "fingerprint": "2af9255caa009789b913e5075072dc86af7b7c85d550201c04730431ecd335b5",
  "created_at": "2026-09-04T10:00:00.000Z",
  "updated_at": "2026-09-04T10:00:00.000Z"
}
```

Store the returned `id` (e.g. `key_aBcDeFgH`). You supply this as the `keyid` parameter in your HTTP `Signature-Input` headers and bind it to your Tenant ACL rules.

### Configure upstream request headers

Your edge proxy or signing service must attach two standard RFC 9421 headers (`Signature-Input` and `Signature`) to all forwarded requests. We recommend you check with your provider should they use an open source library.

#### Construct the base signature

Per RFC 9421 Section 2.5, the signature base is constructed using one line per covered component in the exact order listed in `Signature-Input`, followed by `@signature-params` as the final line:

```text theme={null}
"@method": POST
"@path": /oauth/token
"@signature-params": ("@method" "@path");created=1752019200;expires=1752019500;keyid="key_aBcDeFgH"
```

#### Header examples

Review the following header examples for using `Signature-Input` and `Signature`.

##### Method and path

Example for (`POST` `/oauth/token`)

```http theme={null}
Signature-Input: sig1=("@method" "@path");created=1752019200;expires=1752019500;keyid="key_aBcDeFgH"
Signature: sig1=:Ic2zxAtZmz2iy0g7qMxEGAic6EH8t70Soh+pC6/Y5L8=:
```

##### Query parameter

Example with the `state` parameter using `GET` `/authorize?state=abc123xyz&client_id=myclient`

```http theme={null}
Signature-Input: sig1=("@method" "@path" "@query-param";name="state");created=1752019200;expires=1752019500;keyid="key_aBcDeFgH"
Signature: sig1=:OCnwy3NadPiHa1qmtFVHKaSxLebfdJMjqTPEOByO+yw=:
```

## Configure Tenant ACL rules

To require valid signatures, create a [Tenant ACL rule](https://auth0.com/docs/secure/tenant-access-control-list) that blocks requests based on the `http_message_signature` signal.

### Block unsigned or invalid requests

To block any incoming request that does not contain a valid HTTP Message Signature signed by an authorized key, [configure a `not_match` rule](https://auth0.com/docs/secure/tenant-access-control-list/configure-rules) similar to the sample below. We recommend you [set up monitoring mode](https://auth0.com/docs/secure/tenant-access-control-list/enable-monitoring-mode.md) to evaluate the `not_match` rule.

```http theme={null}
POST /api/v2/network-acls
Content-Type: application/json
Authorization: Bearer {YOUR_MANAGEMENT_API_TOKEN}

{
  "description": "Block requests not signed by trusted edge proxy",
  "active": true,
  "priority": 10,
  "rule": {
    "action": { 
      "block": true 
    },
    "scope": "tenant",
    "not_match": {
      "http_message_signature": {
        "keys": [
          { "id": "key_aBcDeFgH" }
        ]
      }
    }
  }
}
```

## Zero-downtime key rotation

You can rotate signing secrets without interrupting live traffic by assigning multiple active key IDs to an ACL rule.

1. Generate a new key ID from the [Create a Network ACL key](https://auth0.com/docs/api/management/v2/keys/create-keys-network-acls.md) endpoint.

To use the Management API, you need to get a [Management API access token](https://auth0.com/docs/secure/tokens/access-tokens/management-api-access-tokens.md) with the following scopes: `create:network_acl_keys`, `update:network_acls`, and `delete:network_acl_keys`.

2. Update the ACL rule. To do so, add the new key ID to the `http_message_signature.keys` array alongside the active key (up to 10 keys permitted per rule):

```json theme={null}
"keys": [
  { "id": "key_aBcDeFgH" },
  { "id": "key_xYzWvUtS" }
]
```

Before proceeding to the next step, we recommend you manually verify the new key is accepted. There may be a lag between updating the rule and the rule being enforced.

3. Update Edge signing. Update your edge proxy to begin signing incoming traffic using the new keyid (example: `key_xYzWvUtS`).

4. Monitor tenant logs. Inspect the `acls_summary` log event. Check the `valid_signature_key_ids` field inside the log details to verify that incoming traffic is successfully validating under the new key ID:

```json theme={null}
{
  "type": "acls_summary",
  "details": {
    "stats": [
      {
        "acl_id": "acl_abc123",
        "action": "ACTION_TYPE_BLOCK",
        "valid_signature_key_ids": ["key_xYzWvUtS"]
      }
    ]
  }
}
```

5. Decommission the old key. Once `valid_signature_key_ids` no longer references `key_aBcDeFgH`, remove the old key ID from the ACL rule and call the [Delete Network ACL Key](https://auth0.com/docs/api/management/v2/keys/delete-keys-network-acls.md) endpoint:

```http theme={null}
DELETE /api/v2/keys/network-acls/key_aBcDeFgH
```

## Limitations

Review the following limitations:

* You can use up to 10 active keys per tenant and up to 10 key IDs bound per ACL rule.
* Management API key endpoints are limited to 10 RPS for reads (`network_acl_keys_read`) and 5 RPS for writes (`network_acl_keys_write`).
