For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
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.
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
- Set up an agentgateway proxy.
- 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.
From your API management tool, generate an API key. The examples in this guide use
N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy.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}'Create a ConfigMap to store your API key hashes. Each entry represents one valid API key, as a JSON object with a
keyHashand optionalmetadata. 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" } } EOFCreate an AgentgatewayPolicy resource that configures API key authentication for all routes that the Gateway serves, and select the
apikeyConfigMap withconfigMapSelector. The following example uses theStrictvalidation mode, which requires requests to include a validAuthorizationheader 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
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.
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% ...Repeat the request. This time, you provide a valid API key in the
Authorizationheader. 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-foundOther 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.
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(orkeyHash) and optionalmetadata.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" } } EOFReference the Secret in the AgentgatewayPolicy. Reference a single Secret by name with
secretRef, or select multiple Secrets by label withsecretSelector.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 EOFPreRouting phase
By default, API key authentication is enforced during routing. Use the
PreRoutingphase 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 EOFOptional validation mode
Use the
Optionalmode 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.TheOptionalmode 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