Envoy Authz Server¶
This example demonstrates how to run and test the Kyverno Authorization Server in Envoy mode with a JWT-based authentication policy.
It shows how the server evaluates gRPC requests and enforces access rules using token validation.
Prerequisites¶
Before starting, ensure you have:
Tip
You do not need a Kubernetes cluster — the server runs locally and loads policies directly from files.
Step 1: Create a Policy¶
Save the following policy as quick-start.yaml in your working directory:
apiVersion: policies.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
name: quick-start
spec:
evaluation:
mode: Envoy
failurePolicy: Fail
variables:
- name: authorization
expression: object.attributes.request.http.headers[?"authorization"].orValue("").split(" ")
- name: token
expression: >
size(variables.authorization) == 2 && variables.authorization[0].lowerAscii() == "bearer"
? jwt.Decode(variables.authorization[1], "secret")
: null
validations:
- expression: >
variables.token == null || !variables.token.Valid
? envoy.Denied(401).Response()
: null
- expression: >
variables.token.Claims.?role.orValue("") != "admin"
? envoy.Denied(403).Response()
: null
- expression: >
envoy.Allowed().Response()
This policy:
- Denies requests without a valid token (
401). - Denies authenticated users without an admin role (
403). - Allows admin users (
200).
Step 2: Run the Envoy Authz Server¶
Start the Authz Server with Docker:
docker run --rm \
-v ${HOME}/.kube/:/etc/kubeconfig/ \
-v ${PWD}/quick-start.yaml/:/data/policies/quick-start.yaml \
-e KUBECONFIG=/etc/kubeconfig/config \
-p 9081:9081 \
ghcr.io/kyverno/kyverno-envoy-plugin:a83ddce53efe0a35dfe239d3089bdefa19ca4f80 \
serve envoy authz-server --kube-policy-source=false \
--external-policy-source file://data/policies
Expected startup output:
2025-11-04T17:42:32Z INFO HTTP Server starting... {"address": ":9080", "cert": "", "key": ""}
2025-11-04T17:42:32Z INFO GRPC Server starting... {"address": "[::]:9081", "network": "tcp"}
The gRPC server listens on port 9081.
Step 3: Send Requests to the Server¶
Example 1 — Missing Authorization Header¶
grpcurl -plaintext -d @ localhost:9081 envoy.service.auth.v3.Authorization/Check <<EOF
{
"attributes": {
"request": {
"http": {
"headers": {
"authorization": "empty"
}
}
}
}
}
EOF
Response:
Example 2 — Non-admin User Token¶
export ALICE_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIyNDEwODE1MzksIm5iZiI6MTUxNDg1MTEzOSwicm9sZSI6Imd1ZXN0Iiwic3ViIjoiWVd4cFkyVT0ifQ.ja1bgvIt47393ba_WbSBm35NrUhdxM4mOVQN8iXz8lk"
grpcurl -plaintext -d @ localhost:9081 envoy.service.auth.v3.Authorization/Check <<EOF
{
"attributes": {
"request": {
"http": {
"headers": {
"authorization": "bearer $ALICE_TOKEN"
}
}
}
}
}
EOF
Response:
Example 3 — Admin User Token¶
export BOB_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIyNDEwODE1MzksIm5iZiI6MTUxNDg1MTEzOSwicm9sZSI6ImFkbWluIiwic3ViIjoiWVd4cFkyVT0ifQ.veMeVDYlulTdieeX-jxFZ_tCmqQ_K8rwx2OktUHv5Z0"
grpcurl -plaintext -d @ localhost:9081 envoy.service.auth.v3.Authorization/Check <<EOF
{
"attributes": {
"request": {
"http": {
"headers": {
"authorization": "bearer $BOB_TOKEN"
}
}
}
}
}
EOF
Response:
Step 4: Summary¶
- Define a JWT-based Envoy authorization policy.
- Run the Kyverno Envoy Authz Server via Docker.
- Test requests with grpcurl and validate access control decisions.