Documentation
Introduction
Configuration
- HTTPProxy Fundamentals
- Ingress v1 Support
- Virtual Hosts
- Inclusion and Delegation
- TLS Termination
- Upstream TLS
- Request Routing
- External Service Routing
- Request Rewriting
- CORS
- Websockets
- Upstream Health Checks
- Client Authorization
- TLS Delegation
- Rate Limiting
- Access logging
- Cookie Rewriting
- Overload Manager
- JWT Verification
- IP Filtering
- Annotations Reference
- Slow Start Mode
- Tracing Support
- API Reference
Deployment
- Deployment Options
- Contour Configuration
- Upgrading Contour
- Enabling TLS between Envoy and Contour
- Redeploy Envoy
Guides
- Deploying Contour on AWS with NLB
- AWS Network Load Balancer TLS Termination with Contour
- Deploying HTTPS services with Contour and cert-manager
- External Authorization Support
- FIPS 140-2 in Contour
- Using Gatekeeper with Contour
- Using Gateway API with Contour
- Global Rate Limiting
- Configuring ingress to gRPC services with Contour
- Health Checking
- How to enable structured JSON logging
- Creating a Contour-compatible kind cluster
- Collecting Metrics with Prometheus
- How to Configure PROXY Protocol v1/v2 Support
- Contour/Envoy Resource Limits
Troubleshooting
- Envoy Administration Access
- Contour Debug Logging
- Envoy Debug Logging
- Visualize the Contour Graph
- Show Contour xDS Resources
- Profiling Contour
- Contour Operator
- Envoy Container Stuck in Unready State
Resources
- Support Policy
- Compatibility Matrix
- Contour Deprecation Policy
- Release Process
- Frequently Asked Questions
- Tagging
Security
Contribute
JWT Verification
Contour supports verifying JSON Web Tokens (JWTs) on incoming requests, using Envoy’s jwt_authn HTTP filter. Specifically, the following properties can be checked:
- issuer field
- audiences field
- signature, using a configured JSON Web Key Store (JWKS)
- time restrictions (e.g. expiration, not before time)
If verification succeeds, the request will be proxied to the appropriate upstream. If verification fails, an HTTP 401 (Unauthorized) will be returned to the client.
JWT verification is only supported on TLS-terminating virtual hosts.
Configuring providers and rules
A JWT provider is configured for an HTTPProxy’s virtual host, and defines how to verify JWTs:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: jwt-verification
namespace: default
spec:
virtualhost:
fqdn: example.com
tls:
secretName: example-com-tls-cert
jwtProviders:
- name: provider-1
issuer: example.com
audiences:
- audience-1
- audience-2
remoteJWKS:
uri: https://example.com/jwks.json
timeout: 1s
cacheDuration: 5m
forwardJWT: true
routes:
...
The provider above requires JWTs to have an issuer of example.com, an audience of either audience-1 or audience-2, and a signature that can be verified using the configured JWKS.
It also forwards the JWT to the backend via the Authorization
header after successful verification.
To apply a JWT provider as a requirement to a given route, specify a jwtVerificationPolicy
for the route:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: jwt-verification
namespace: default
spec:
virtualhost:
fqdn: example.com
tls:
secretName: example-com-tls-cert
jwtProviders:
- name: provider-1
...
routes:
- conditions:
- prefix: /
jwtVerificationPolicy:
require: provider-1
services:
- name: s1
port: 80
- conditions:
- prefix: /css
services:
- name: s1
port: 80
In the above example, the default route requires requests to carry JWTs that can be verified using provider-1.
The second route excludes requests to paths starting with /css
from JWT verification, because it does not have a JWT verification policy.
Configuring TLS validation for the JWKS server
By default, the JWKS server’s TLS certificate will not be validated, but validation can be requested by setting the spec.virtualhost.jwtProviders[].remoteJWKS.validation
field.
This field has mandatory caSecret
and subjectName
fields, which specify the trusted root certificates with which to validate the server certificate and the expected server name.
The caSecret
can be a namespaced name of the form <namespace>/<secret-name>
.
If the CA secret’s namespace is not the same namespace as the HTTPProxy
resource,
TLS Certificate Delegation must be used to allow the owner of the CA certificate secret to delegate, for the purposes of referencing the CA certificate in a different namespace, permission to Contour to read the Secret object from another namespace.
Note: If spec.virtualhost.jwtProviders[].remoteJWKS.validation
is present, spec.virtualhost.jwtProviders[].remoteJWKS.uri
must have a scheme of https
.
Setting a default provider
The previous section showed how to explicitly require JWT providers for specific routes.
An alternate approach is to define a JWT provider as the default by specifying default: true
for it, in which case it is automatically applied to all routes unless they disable JWT verification.
The example from the previous section could alternately be configured as follows:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: jwt-verification
namespace: default
spec:
virtualhost:
fqdn: example.com
tls:
secretName: example-com-tls-cert
jwtProviders:
- name: provider-1
default: true
...
routes:
- conditions:
- prefix: /
services:
- name: s1
port: 80
- conditions:
- prefix: /css
jwtVerificationPolicy:
disabled: true
services:
- name: s1
port: 80
In this case, the default route automatically has provider-1 applied, while the /css
route explicitly disables JWT verification.
One scenario where setting a default provider can be particularly useful is when using HTTPProxy inclusion. Setting a default provider in the root HTTPProxy allows all routes in the child HTTPProxies to automatically have JWT verification applied. For example:
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: jwt-verification-root
namespace: default
spec:
virtualhost:
fqdn: example.com
tls:
secretName: example-com-tls-cert
jwtProviders:
- name: provider-1
default: true
...
includes:
- name: jwt-verification-child
namespace: default
conditions:
- prefix: /blog
---
apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: jwt-verification-child
namespace: default
spec:
routes:
- conditions:
- prefix: /
services:
- name: s1
port: 80
In this case, all routes in the child HTTPProxy will automatically have JWT verification applied, without the owner of this HTTPProxy needing to configure it explicitly.
API documentation
For more information on the HTTPProxy API for JWT verification, see: