This is the "latest" release of Envoy Gateway, which contains the most recent commits from the main branch.
This release might not be stable.
Please refer to the /docs documentation for the most current information.
Client Certificate Authorization
5 minute read
Overview
Envoy Gateway supports authorizing requests based on the TLS client certificate
presented during the mTLS handshake. When a SecurityPolicy rule uses
principal.clientCert, Envoy evaluates the validated client certificate against
one or more match criteria before allowing or denying the request.
Supported match types:
| Field | Matches |
|---|---|
subject | Subject Distinguished Name (DN) of the certificate, RFC 4514 string form |
subjectAltNames.uris | URI Subject Alternative Names (e.g. SPIFFE IDs) |
subjectAltNames.dnsNames | DNS Subject Alternative Names |
Note: Email address, IP address, and OtherName SAN types are not currently supported. Specifying them will produce a validation error.
Prerequisites
mTLS must be configured on the gateway listener
clientCert authorization matches against the certificate that the client
presents during the TLS handshake. This certificate is only available when
mutual TLS (mTLS) is enabled on the listener.
Configure mTLS by creating a ClientTrafficPolicy that targets the relevant
listener and sets spec.tls.clientValidation.caCertificateRefs:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
name: mtls-policy
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: my-gateway
sectionName: https
tls:
clientValidation:
caCertificateRefs:
- kind: Secret
group: ""
name: my-ca-cert
Without mTLS configured, no client certificate is available and
clientCert principals will never match.
Follow the steps below to install Envoy Gateway and the example manifest. Before proceeding, you should be able to query the example backend using HTTP.
Expand for instructions
Install the Gateway API CRDs and Envoy Gateway using Helm:
Gateway API CRD compatibilityThis command installs Gateway API CRDs. If your Kubernetes provider already manages compatible Gateway API CRDs for the cluster, use the provider-managed Gateway API CRD install steps instead.
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.0.0-latest -n envoy-gateway-system --create-namespaceInstall the GatewayClass, Gateway, HTTPRoute and example app:
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/latest/quickstart.yaml -n defaultVerify Connectivity:
Get the External IP of the Gateway:
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/getThe above command should succeed with status code 200.
Get the name of the Envoy service created the by the example Gateway:
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Get the deployment of the Envoy service created the by the example Gateway:
export ENVOY_DEPLOYMENT=$(kubectl get deploy -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')Port forward to the Envoy service:
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &Curl the example app through Envoy proxy:
curl --verbose --header "Host: www.example.com" http://localhost:8888/getThe above command should succeed with status code 200.
URI SAN Authorization
Use subjectAltNames.uris to allow requests from clients whose certificate
carries a specific URI SAN (e.g. a SPIFFE ID).
Example
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: authz-uri-san
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
authorization:
defaultAction: Deny
rules:
- name: allow-spiffe-workload
action: Allow
principal:
clientCert:
subjectAltNames:
uris:
- type: Exact
value: "spiffe://my-trust-domain/ns/prod/sa/frontend"
Only clients whose certificate contains the URI SAN
spiffe://my-trust-domain/ns/prod/sa/frontend (exact match) are allowed.
All other requests are denied by the default action.
StringMatch supports Exact, Prefix, Suffix, and RegularExpression
match types for URI SANs.
DNS SAN Authorization
Use subjectAltNames.dnsNames to allow requests from clients whose certificate
carries a specific DNS SAN.
Example
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: authz-dns-san
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
authorization:
defaultAction: Deny
rules:
- name: allow-client-dns
action: Allow
principal:
clientCert:
subjectAltNames:
dnsNames:
- type: Exact
value: "client.example.com"
Only clients presenting a certificate with the DNS SAN client.example.com
are permitted.
Subject DN Authorization
Use subject to match against the certificate’s Subject Distinguished Name.
The DN is represented as an RFC 4514 string, for example
CN=client.example.com,O=Example Inc.,C=US. Use RegularExpression when you
need to match a subset of the DN.
Example: exact Subject DN
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: authz-subject-dn
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
authorization:
defaultAction: Deny
rules:
- name: allow-exact-subject
action: Allow
principal:
clientCert:
subject:
type: Exact
value: "CN=allowed-client,O=Example Inc."
Example: regex Subject DN
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: authz-subject-regex
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
authorization:
defaultAction: Deny
rules:
- name: allow-org-clients
action: Allow
principal:
clientCert:
subject:
type: RegularExpression
value: ".*O=Example Inc\\..*"
Combining Subject DN and SANs
When both subject and subjectAltNames are specified in the same
clientCert entry, both must match for the principal to be satisfied.
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
name: authz-combined
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: my-route
authorization:
defaultAction: Deny
rules:
- name: allow-specific-workload
action: Allow
principal:
clientCert:
subject:
type: RegularExpression
value: ".*O=Acme Corp.*"
subjectAltNames:
uris:
- type: Prefix
value: "spiffe://acme.example/ns/prod/"
Behavior Notes
- mTLS required: If mTLS is not configured, no certificate is presented and
clientCertprincipals will never match any request. - AND semantics between
subjectandsubjectAltNames: When bothsubjectandsubjectAltNamesare set, the Subject DN must match and the SAN group must match. - OR semantics within
subjectAltNames: AllurisanddnsNamesentries OR-combine into a single group — a certificate matches if any one of the listed URI or DNS identities matches. URI and DNS SANs are not AND-combined across types, because a workload cert typically carries a URI SAN and a service cert a DNS SAN, rarely both. - Rule evaluation order: Rules are evaluated in the order they are defined. The first matching rule is applied.
- HTTPRoute / GRPCRoute only:
clientCertprincipal is not applicable to TCPRoute targets.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.