hashicorp/consul
API gateway
The Consul API gateway is a mesh ingress proxy with rich HTTP routing, TLS termination from config entries, and JWT-based authorization. It's modeled loosely on the Kubernetes Gateway API.
Pieces
| Piece | Where |
|---|---|
api-gateway config entry |
agent/structs/config_entry_gateways.go |
bound-api-gateway (controller-managed) |
agent/structs/config_entry_gateways.go |
http-route, tcp-route config entries |
agent/structs/config_entry_routes.go |
inline-certificate, file-system-certificate |
agent/structs/config_entry_inline_certificate.go, agent/structs/config_entry_file_system_certificate.go |
jwt-provider config entry |
agent/structs/config_entry_jwt_provider.go |
| Reconciler controller | agent/consul/gateways/ |
| Proxy config snapshot | agent/proxycfg/api_gateway.go |
| xDS listener builder | agent/xds/listeners_apigateway.go, agent/xds/listeners.go |
| Limits | agent/proxycfg/api_gateway_limits_test.go |
| CLI / docs | docs in docs/; CLI flows through consul config for entries |
Resource model
graph LR
APIGW[api-gateway] -->|listeners| BoundGW[bound-api-gateway]
HTTPRoute[http-route] -.parents.-> APIGW
TCPRoute[tcp-route] -.parents.-> APIGW
HTTPRoute -->|backendRefs| Service
InlineCert[inline-certificate] -.referenced by.-> APIGW
FSCert[file-system-certificate] -.referenced by.-> APIGW
JWTProvider[jwt-provider] -.referenced by.-> HTTPRouteapi-gatewaydefines listeners (port + protocol + TLS).http-route/tcp-routeattach to a listener and define routing rules.- A controller (
agent/consul/gateways/) reconcilesapi-gateway+ routes into abound-api-gatewayresource that contains the resolved attachments. inline-certificateandfile-system-certificateprovide TLS material; the latter is for environments where certs are mounted from disk (vs. checked into Raft).jwt-providerdefines OIDC/JWT verification config that routes can reference for per-route auth.
Reconciliation
The controller in agent/consul/gateways/:
- Watches
api-gateway,http-route,tcp-route,inline-certificate,file-system-certificate. - For each
api-gateway, computes which routes attach (matching parent ref + section name). - Validates listener uniqueness (no port conflicts), TLS material presence, route protocol compatibility.
- Writes a
bound-api-gatewayreflecting the attachment state and any errors asStatus. - Publishes events that the proxy config manager picks up.
This pattern predates the v2 resource framework but is conceptually similar — it's an in-tree controller using config entries as the data model.
Snapshot and xDS path
agent/proxycfg/api_gateway.go builds an APIGateway sub-snapshot containing:
- Bound listeners and their TLS material (resolved from cert config entries).
- Route bindings: HTTP virtual hosts + filter chains + per-route JWT requirements.
- Backend services and their discovery chains.
agent/xds/listeners_apigateway.go translates this into:
- One Envoy listener per gateway listener.
- HTTP connection manager filters that include the JWT authn filter (
agent/xds/jwt_authn.go) and the per-route filter chain (agent/xds/gw_per_route_filters_ce.go). - HCM virtual hosts derived from
http-routerules. - TLS context with SDS for cert material.
tcp-route listeners use the simpler TCP proxy path.
TLS material
Two flavors:
inline-certificate— the cert and key are stored inline in the config entry (encrypted at rest if Vault is the CA provider). Convenient but the cert lives in the Raft log.file-system-certificate— references a path on disk; the gateway proxy reads the cert at start time. Useful when certs are managed externally (e.g., cert-manager).
Both are exposed to Envoy via SDS in agent/xds/secrets.go.
JWT authorization
A jwt-provider config entry defines:
- Issuer URL or local JWKS.
- Audiences.
- Cache duration for JWKS.
- Forwarding mode (forward header to upstream, or strip).
Routes reference providers in their JWTFilter block, listing required audiences/scopes. agent/xds/jwt_authn.go builds the Envoy JWT-authn filter; agent/xds/rbac.go builds matching RBAC rules.
Per-route filters
agent/xds/gw_per_route_filters_ce.go (CE) defines the limited per-route filter set available in CE. Enterprise has additional filters (rate limiting, custom envoy filters) that mount via the same plumbing.
Operator workflow
# Define the gateway
consul config write api-gateway.hcl
# Define routes and certs
consul config write web-route.hcl
consul config write web-cert.hcl
# Verify the resolved state
consul config read -kind bound-api-gateway -name web-gw
# Run the gateway proxy (typically via consul-k8s or dataplane)The gateway proxy itself is just an Envoy fed by Consul's xDS server (or the dataplane). The agent config and proxy registration follow the same pattern as any other gateway kind.
Integration points
- Intentions still apply to traffic that flows from the gateway to mesh services.
- Mesh gateway — when the api-gateway sends to a service in another DC/peer, traffic hops through the mesh gateway just like sidecar traffic does.
- Streaming — config entry changes propagate via the standard subscribe path; routes hot-reload.
Entry points for modification
- Add a new listener protocol: extend
agent/structs/config_entry_gateways.goand the validators, then teachagent/proxycfg/api_gateway.goandagent/xds/listeners_apigateway.goto assemble it. - Add a per-route filter type: see
agent/xds/gw_per_route_filters_ce.go. - Add a route attribute (e.g., timeouts): extend
agent/structs/config_entry_routes.goand propagate through the snapshot + xDS builder.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.