---
title: "Add JWT Authentication to Your Envoy API"
description: "Secure your Envoy API using JWT authentication with JWKS."
canonicalUrl: "https://zuplo.com/use-cases/api-key-auth/c/envoy/jwt-backend"
framework: "Envoy"
language: "C++"
authStrategy: "JWT with JWKS"
pageType: use-case
---

# Add JWT Authentication to Your Envoy API

Secure your Envoy API using JWT authentication with JWKS.

## How Zuplo Handles It

Let Zuplo issue short-lived JWTs signed with a JWKS your Envoy backend can verify — no long-lived API keys touch your origin.

## Envoy Backend Code

```yaml
# envoy.yaml
static_resources:
  listeners:
    - address:
        socket_address: { address: 0.0.0.0, port_value: 80 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_http
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      routes:
                        - match: { prefix: "/protected" }
                          route: { cluster: service_backend }
                          typed_per_filter_config:
                            envoy.filters.http.jwt_authn:
                              "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.PerRouteFilterConfig
                              requirement_name: "example-requirement"
                http_filters:
                  - name: envoy.filters.http.jwt_authn
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
                      providers:
                        example_provider:
                          issuer: "https://my-api-a32f34.zuplo.api/__zuplo/issuer"
                          from_headers:
                            - name: Authorization
                              value_prefix: "Bearer "
                          remote_jwks:
                            http_uri:
                              uri: "https://my-api-a32f34.zuplo.api/__zuplo/issuer/.well-known/jwks.json"
                              cluster: jwks_cluster
                            cache_duration: 600s
                      rules:
                        - match:
                            prefix: "/protected"
                          requires:
                            provider_name: "example_provider"
                  - name: envoy.filters.http.router
  clusters:
    - name: service_backend
      connect_timeout: 0.25s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: service_backend
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: service.backend
                      port_value: 8080
    - name: jwks_cluster
      connect_timeout: 0.25s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: jwks_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: my-api.zuplo.com
                      port_value: 443
      transport_socket:
        name: envoy.transport_sockets.tls
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
```

## Example Request

```bash
curl -X GET \
  'https://your-api.zuplo.dev/your-route' \
  -H 'Authorization: Bearer YOUR_API_KEY'
```

## Learn More

- [API Key Authentication on Zuplo](https://zuplo.com/docs/policies/api-key-auth-inbound)
- [JWT Authentication on Zuplo](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
- [All use cases](https://zuplo.com/use-cases)
