Skip to content
agentgateway has joined the Agentic AI FoundationLearn more

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Page as Markdown

API key auth

Set up API key auth to secure requests to an LLM, MCP server, or agent.

API keys are secure, long-lived UUIDs that clients provide when they send a request to your service. You might use API keys in the following scenarios:

  • You know the set of users that need access to your service. These users do not change often, or you have automation that easily generates or deletes the API key when the users do change.
  • You want direct control over how the credentials are generated and expire.
When you use API keys, your services are only as secure as the API keys. Storing and rotating the API key securely is up to the user.

API key auth in agentgateway

The agentgateway proxy comes with built-in API key auth support via the AgentgatewayPolicy resource. To secure your services with API keys, first provide your agentgateway proxy with your API keys in the form of Kubernetes secrets. Then in the AgentgatewayPolicy resource, you refer to the secrets in one of two ways.

  • Specify a label selector that matches the label of one or more API key secrets. Labels are the more flexible, scalable approach.
  • Refer to the name and namespace of each secret.

Important

ConfigMaps with hashed keys (as opposed to Secrets) are the recommended way to store API keys. If you need to use Kubernetes Secrets, refer to Store keys in a Secret.

The proxy matches a request to a route that is secured by the external auth policy. The request must have a valid API key in the Authorization header to be accepted. You can configure the name of the expected header. If the header is missing, or the API key is invalid, the proxy denies the request and returns a 401 response.

The following diagram illustrates the flow:

    sequenceDiagram
    participant C as Client / Agent
    participant AGW as Agentgateway Proxy
    participant K8s as K8s Secrets<br/>(API Keys)
    participant Backend as Backend<br/>(LLM / MCP / Agent / HTTP)

    C->>AGW: POST /api<br/>(no Authorization header)

    AGW->>AGW: API key auth check:<br/>No API key found

    AGW-->>C: 401 Unauthorized<br/>"no API Key found"

    Note over C,Backend: Retry with API key

    C->>AGW: POST /api<br/>Authorization: Bearer N2YwMDIx...

    AGW->>K8s: Lookup referenced secret<br/>(by name or label selector)
    K8s-->>AGW: Secret found

    AGW->>AGW: Compare API key from<br/>request header vs secret

    alt mode: Strict — Key valid
        AGW->>Backend: Forward request
        Backend-->>AGW: Response
        AGW-->>C: 200 OK + Response
    else Key invalid
        AGW-->>C: 401 Unauthorized
    end

    Note over C,Backend: Optional Mode

    rect rgb(245, 245, 255)
        Note over AGW: mode: Optional<br/>• Valid API key → forward<br/>• Invalid API key → 401 reject<br/>• No API key → allow through
    end
  

Before you begin

  1. Set up an agentgateway proxy.
  2. Install the httpbin sample app.

Set up API key auth

Store your API keys in a Kubernetes ConfigMap so that you can reference them in an AgentgatewayPolicy resource. Because a ConfigMap is not confidential, each entry stores a SHA-256 hash of the API key (keyHash) rather than the raw key. Clients still send the raw key in the Authorization header; the proxy hashes the presented key and compares it to the stored hash, so the plaintext key never has to exist in the cluster. This is the recommended way to store API keys. To use a Secret instead, see Store keys in a Secret.

  1. From your API management tool, generate an API key. The examples in this guide use N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy.

  2. Generate a sha256:<hex> hash of the API key. The hash is computed over the exact key bytes, so do not include a trailing newline.

    printf '%s' 'N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy' | sha256sum | awk '{print "sha256:"$1}'
  3. Create a ConfigMap to store your API key hashes. Each entry represents one valid API key, as a JSON object with a keyHash and optional metadata. Add a label so that the policy can select the ConfigMap.

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: apikey
      namespace: agentgateway-system
      labels:
        app: httpbin
    data:
      api-key: |
        {
          "keyHash": "sha256:ec831936fbbab1232344d9da271d1629fabc992aef393d7d54735b210d4ff166",
          "metadata": {
            "group": "sales"
          }
        }
    EOF
  4. Create an AgentgatewayPolicy resource that configures API key authentication for all routes that the Gateway serves, and select the apikey ConfigMap with configMapSelector. The following example uses the Strict validation mode, which requires requests to include a valid Authorization header to be authenticated successfully. For other common configuration examples, see Other configuration examples.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: apikey-auth
      namespace: agentgateway-system
    spec:
      targetRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: agentgateway-proxy
      traffic:
        apiKeyAuthentication:
          mode: Strict
          configMapSelector:
            matchLabels:
              app: httpbin
    EOF
Every entry in a selected ConfigMap must use keyHash. If an entry uses a raw key, that entry is rejected and the policy reports a PartiallyValid status, while the valid entries continue to work.

After you apply the policy, verify that API key authentication is enforced.

  1. Send a request to the httpbin app without an API key. Verify that the request fails with a 401 HTTP response code.

    curl -vi "${INGRESS_GW_ADDRESS}:80/headers" -H "host: www.example.com"

    Example output:

    ...
    < HTTP/1.1 401 Unauthorized
    HTTP/1.1 401 Unauthorized
    
    api key authentication failure: no API Key found%
    ...
  2. Repeat the request. This time, you provide a valid API key in the Authorization header. Verify that the request now succeeds.

    curl -vi "${INGRESS_GW_ADDRESS}:80/headers" \
    -H "host: www.example.com" \
    -H "Authorization: Bearer N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy"

    Example output:

    ...
    * Request completely sent off
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < access-control-allow-credentials: true
    access-control-allow-credentials: true
    < access-control-allow-origin: *
    access-control-allow-origin: *
    < content-type: application/json; encoding=utf-8
    content-type: application/json; encoding=utf-8
    < content-length: 148
    content-length: 148
    <
    
    {
      "headers": {
        "Accept": [
          "*/*"
        ],
        "Host": [
          "www.example.com"
        ],
        "User-Agent": [
          "curl/8.7.1"
        ]
      }
    }
    ...

Cleanup

You can remove the resources that you created in this guide.
kubectl delete AgentgatewayPolicy apikey-auth -n agentgateway-system --ignore-not-found
kubectl delete configmap apikey -n agentgateway-system --ignore-not-found
kubectl delete secret apikey -n agentgateway-system --ignore-not-found

Other configuration examples

Review other common configuration examples.

Store keys in a Secret

To store API keys in a Kubernetes Secret instead of a ConfigMap, create a Secret and reference it in the policy with either secretRef (a single Secret) or secretSelector (multiple Secrets selected by label). Unlike a ConfigMap, a Secret entry can use a raw key or a keyHash.

  1. Create a Secret to store your API keys. Each entry represents one valid API key, as the raw key string or a JSON object with a key (or keyHash) and optional metadata.

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: apikey
      namespace: agentgateway-system
      labels:
        app: httpbin
    stringData:
      api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy
      client2: RjBiNjcyLWM0YzQtMGJkNC04M2d3LWM1UzNHTi1lWklETXdZMk4
      client3: |
        {
          "key": "YWJjMTIzLTRlZjUtNjc4OS1hYmNkLWVmMTIzNDU2Nzg5MA",
          "metadata": {
            "group": "sales"
          }
        }
    EOF
  2. Reference the Secret in the AgentgatewayPolicy. Reference a single Secret by name with secretRef, or select multiple Secrets by label with secretSelector.

kubectl apply -f- <<EOF
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayPolicy
metadata:
  name: apikey-auth
  namespace: agentgateway-system
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: agentgateway-proxy
  traffic:
    apiKeyAuthentication:
      mode: Strict
      secretRef:
        name: apikey
EOF

PreRouting phase

By default, API key authentication is enforced during routing. Use the PreRouting phase to validate API keys before any routing decision is made. This is useful when you want to enforce authentication for all traffic at the gateway level, regardless of the route.

kubectl apply -f- <<EOF
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayPolicy
metadata:
  name: apikey-auth
  namespace: agentgateway-system
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: agentgateway-proxy
  traffic:
    phase: PreRouting
    apiKeyAuthentication:
      mode: Strict
      configMapSelector:
        matchLabels:
          app: httpbin
EOF

Optional validation mode

Use the Optional mode to validate API keys when present, but allow requests without an API key. This mode is useful for services that offer both authenticated and unauthenticated access.

The Optional mode allows requests without an API key. Use this mode only when you intend to allow unauthenticated access to your services.
kubectl apply -f- <<EOF
apiVersion: agentgateway.dev/v1alpha1
kind: AgentgatewayPolicy
metadata:
  name: apikey-auth
  namespace: agentgateway-system
spec:
  targetRefs:
    - group: gateway.networking.k8s.io
      kind: Gateway
      name: agentgateway-proxy
  traffic:
    apiKeyAuthentication:
      mode: Optional
      configMapSelector:
        matchLabels:
          app: httpbin
EOF
Access loggingBackendTLS
Was this page helpful?
Agentgateway assistant

Ask me anything about agentgateway configuration, features, or usage.

Note: AI-generated content might contain errors; please verify and test all returned information.

Tip: one topic per conversation gives the best results. Use the + button in the chat header to start a new conversation.

Switching topics? Starting a new conversation improves accuracy.
↑↓ navigate select esc dismiss

What could be improved?

Your feedback helps us improve assistant answers and identify docs gaps we should fix.

Need more help? Join us on Discord: https://discord.gg/y9efgEmppm

Want to use your own agent? Add the Solo MCP server to query our docs directly. Get started here: https://search.solo.io/.