API key auth
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.
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 secret so that you can reference it in an AgentgatewayPolicy resource.
-
From your API management tool, generate an API key. The examples in this guide use
N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy. -
Create a Kubernetes secret to store your API key.
kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: apikey namespace: agentgateway-system labels: app: httpbin type: extauth.solo.io/apikey stringData: api-key: N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy EOF -
Verify that the secret is created. Note that the
data.api-keyvalue is base64 encoded.kubectl get secret apikey -n agentgateway-system -oyaml -
Create an AgentgatewayPolicy resource that configures API key authentication for all routes that the Gateway serves and reference the
apikeysecret that you created earlier. The following example uses theStrictvalidation mode, which requires request 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 secretRef: name: apikey EOF -
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"curl -vi "localhost:8080/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"curl -vi "localhost:8080/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
kubectl delete secret apikey -n agentgateway-systemOther configuration examples
Review other common configuration examples.
Label selectors
Refere to your API key secret by using label selectors.
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
secretSelector:
matchLabels:
app: httpbin
EOFOptional 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.
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
secretRef:
name: apikey
EOF