Introduction
Across this series the gateway became the one path your tools, models, and agents share. That makes it the right place to enforce who may call what, and the one place that can tell you what happened. This tutorial adds an authentication policy to the gateway and reads the logs it produces for every request.
Step 1 — Expose a backend to protect
If you still have a route from an earlier tutorial, use it. Otherwise, deploy the httpbin sample and route to it:
kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/examples/httpbin.yaml
kubectl apply -f- <<'EOF'
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
spec:
parentRefs:
- name: agentgateway-proxy
namespace: agentgateway-system
hostnames: ["www.example.com"]
rules:
- backendRefs:
- name: httpbin
port: 8000
EOF
Step 2 — Enforce API-key authentication
Store one or more keys in a Secret:
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
Attach an AgentgatewayPolicy that requires a valid key. This one targets the whole agentgateway-proxy Gateway, so it covers every 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:
apiKeyAuthentication:
mode: Strict
secretRef:
name: apikey
EOF
Step 3 — Test the gate
Port-forward the proxy:
kubectl port-forward deployment/agentgateway-proxy -n agentgateway-system 8080:80
A request with no key is rejected:
curl -s -o /dev/null -w "HTTP %{http_code}\n" localhost:8080/headers -H "host: www.example.com"
HTTP 401
The same request with a valid Authorization: Bearer key passes:
curl -s -o /dev/null -w "HTTP %{http_code}\n" localhost:8080/headers \
-H "host: www.example.com" \
-H "Authorization: Bearer N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy"
HTTP 200
The gateway enforced the policy before the request reached the backend.
Step 4 — Read the access logs
agentgateway logs every request it handles. Watch them on the proxy:
kubectl logs deploy/agentgateway-proxy -n agentgateway-system --tail=5
... route=httpbin/httpbin http.method=GET http.host=www.example.com http.path=/headers
http.status=401 protocol=http error="api key authentication failure: no API Key found"
reason=APIKeyAuth duration=1ms
... route=httpbin/httpbin endpoint=10.244.0.7:8080 http.method=GET http.host=www.example.com
http.path=/headers http.status=200 protocol=http duration=4ms
Each line records the route, method, host, path, status, protocol, and duration — and, for the rejected call, the exact reason (APIKeyAuth). The same logging covers MCP, LLM, and A2A traffic, with the protocol named on each line, so one stream answers “what did the agents do, and what was allowed?”
For distributed traces across agents and tools, agentgateway exports OpenTelemetry; see the tracing docs linked below.
Going further
- Finer-grained rules. You can scope a policy to a single
HTTPRoute, and CEL-based RBAC restricts which caller may use which tool or model. - Other auth methods. JWT authentication validates tokens from your identity provider.
- Tracing and metrics. Point the gateway at an OpenTelemetry collector for end-to-end traces and Prometheus-style metrics.
Clean up
kubectl delete agentgatewaypolicy apikey-auth -n agentgateway-system
kubectl delete secret apikey -n agentgateway-system
kubectl delete httproute httpbin -n httpbin
To remove the whole lab cluster:
kind delete cluster --name agw-lab
Series wrap-up
You started with an empty cluster and finished with an agent gateway that routes tools (MCP), models (LLM), and agents (A2A) through one place, with authentication enforced and every request logged. The same setup runs on any Kubernetes cluster you operate, on open-source components.
Summary
- An
AgentgatewayPolicywithtraffic.apiKeyAuthenticationenforces keys at the gateway; atargetRefscopes it to a Gateway or a single route. - Keys live in a Secret of type
extauth.solo.io/apikey; clients sendAuthorization: Bearer <key>. - The gateway logs every request — route, status, protocol, duration, and the auth reason — across MCP, LLM, and A2A traffic.
- CEL RBAC, JWT auth, and OpenTelemetry tracing extend this for production.
