BYO ext auth service
Bring your own external authorization service to protect requests that go through your Gateway.
About external auth
Kgateway lets you integrate your own external authorization service to your Gateway. Then, this external authorization service makes authorization decisions for requests that go through the Gateway, as shown in the following diagram.
sequenceDiagram
participant Client
participant Gateway
participant Ext Auth
participant Backend
Client->>Gateway: 1. HTTP Request
Gateway->>Ext Auth: 2. Authorization Request
Ext Auth-->>Gateway: 3. Authorization Decision
alt Authorized
Gateway->>Backend: 4. Forward Request
Backend-->>Gateway: Response
Gateway-->>Client: Response
else Not Authorized
Gateway-->>Client: 5. 403 Forbidden
end
- The Client sends a request to the Gateway.
- The Gateway forwards the request to the Ext Auth service.
- The Ext Auth service makes a decision as to whether the request is authorized, based on headers, parameters, or other credentials.
- If authorized, the Gateway forwards the request to the Backend app, which then sends back a response to the Client through the Gateway.
- If not authorized, the Gateway rejects the request and by default returns a 403 Forbidden response to the Client.
Before you begin
Deploy your own external authorization service
Deploy your own external authorization service as a backend service that is accessible to your agentgateway proxy.
-
Deploy your external authorization service. The following example uses the Istio external authorization service for quick testing purposes. This service is configured to allow requests with the
x-ext-authz: allowheader.kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: namespace: agentgateway-system name: ext-authz labels: app: ext-authz spec: replicas: 1 selector: matchLabels: app: ext-authz template: metadata: labels: app: ext-authz app.kubernetes.io/name: ext-authz spec: containers: - image: gcr.io/istio-testing/ext-authz:1.25-dev name: ext-authz ports: - containerPort: 9000 EOF -
Create a Service for the Deployment that your proxy can access.
kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: namespace: agentgateway-system name: ext-authz labels: app: ext-authz spec: ports: - port: 4444 targetPort: 9000 protocol: TCP appProtocol: kubernetes.io/h2c selector: app: ext-authz EOF
Create external auth policy
You can apply a policy at two levels: the Gateway level or the HTTPRoute level. If you apply the policy at both levels, the request must pass both policies to be authorized.
-
Send a test request to the OpenAI backend. Verify that you get back a 200 HTTP response code and that no authorization is required.
curl -v "${INGRESS_GW_ADDRESS}:8080/openai" -H content-type:application/json -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'curl -v "localhost:8080/openai" -H content-type:application/json -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'Example output:
HTTP/1.1 200 OK ... -
Create an AgentgatewayPolicy that applies to the Gateway and references the external authorization service that you created. Note that you can also set the
targetRefsto select an HTTPRoute, which is demonstrated in later steps.kubectl apply -f - <<EOF apiVersion: agentgateway.dev/v1alpha1 kind: AgentgatewayPolicy metadata: namespace: agentgateway-system name: gateway-ext-auth-policy labels: app: ext-authz spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: agentgateway-proxy traffic: extAuth: backendRef: name: ext-authz namespace: agentgateway-system port: 4444 grpc: {} EOF -
Repeat your request to the OpenAI backend and verify that the request is denied.
curl -v "${INGRESS_GW_ADDRESS}:8080/openai" -H content-type:application/json -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'curl -v "localhost:8080/openai" -H content-type:application/json -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'Example output: Note the 403 Forbidden response, along with the special
x-ext-authz*headers that the Istio external authorization service adds to the request to explain the decision.* upload completely sent off: 268 bytes < HTTP/1.1 403 Forbidden < content-type: text/plain < content-length: 29 < * Connection #0 to host localhost left intact denied by ext_authz for not found header `x-ext-authz: allow` in the request% -
Send another request, this time with the
x-ext-authz: allowheader. The Istio external authorization service is configured to allow requests with this header. Therefore, the request succeeds.curl -v "${INGRESS_GW_ADDRESS}:8080/openai" -H content-type:application/json \ -H "x-ext-authz: allow" \ -H "x-ai-api-key:N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy" \ -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'curl -v "localhost:8080/openai" -H content-type:application/json \ -H "x-ext-authz: allow" \ -H "x-ai-api-key:N2YwMDIxZTEtNGUzNS1jNzgzLTRkYjAtYjE2YzRkZGVmNjcy" \ -d '{ "model": "gpt-3.5-turbo", "messages": [ { "role": "system", "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair." }, { "role": "user", "content": "Write 5 sentences." } ] }'
Cleanup
You can remove the resources that you created in this guide.kubectl delete AgentgatewayPolicy gateway-ext-auth-policy -n agentgateway-system
kubectl delete deployment ext-authz -n agentgateway-system
kubectl delete service ext-authz -n agentgateway-system