How would you design TLSRoute and frontend mTLS with Kubernetes Gateway API?
1. Scenario, goals, and non-goals
An infrastructure team operates a shared Gateway while application teams deploy services in their own namespaces. A payment service requires the Gateway to never see plaintext, an internal management service requires client-certificate validation at the edge, and auditors require route changes and handshake failures to be recorded. Teams should publish routes independently while certificate, backend, and listener permissions remain constrained.
State the non-goal first: Gateway API resources express intent. Concrete TLS implementation, load-balancing behavior, and certificate storage remain properties of the GatewayClass controller. The design therefore needs a controller capability matrix and compatibility checks; behavior from one implementation cannot be treated as an API guarantee.
2. Decompose the Gateway API 1.5 capabilities
Gateway API 1.5 moves TLSRoute, frontend client-certificate validation, and related backend TLS capabilities toward stable support, and promotes ReferenceGrant to v1. TLSRoute matches a hostname from the TLS handshake's SNI and forwards the connection to a backend; a listener can use Passthrough or Terminate.
In Passthrough, the Gateway proxies encrypted bytes and the backend owns the certificate and handshake. In Terminate, TLS ends at the Gateway and decrypted TCP is sent to the backend. Key ownership, data visibility, and policy execution points differ, so performance alone cannot decide between them.
3. Design resources and ownership
The platform team creates the Gateway and listeners; application teams create TLSRoute objects bound to named listeners. Use parentRefs.sectionName to bind a route to an explicit listener instead of allowing one route to claim an entire Gateway. Hostnames, ports, protocols, and certificate references are policy inputs for review.
This resource pair expresses passthrough intent:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: shared-edge
namespace: infra
spec:
gatewayClassName: example-gateway-class
listeners:
- name: tls-passthrough
protocol: TLS
port: 8443
tls:
mode: Passthrough
---
apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: payments
namespace: payments
spec:
parentRefs:
- name: shared-edge
namespace: infra
sectionName: tls-passthrough
hostnames: ["pay.example.com"]
rules:
- backendRefs:
- name: payments
port: 8443Cross-namespace references must pass the controller's authorization mechanism and be explicitly allowed by ReferenceGrant or an equivalent policy. Do not rely on default visibility.
4. Choose between Passthrough and Terminate
Passthrough means the Gateway holds no private key and sees no application protocol. It fits strict end-to-end encryption, direct backend mutual TLS, or encrypted TCP requirements. The trade-off is that the Gateway cannot route on HTTP content, apply a uniform application-layer limit, or validate client certificates at the edge; backends carry handshake and certificate-rotation work.
Terminate centralizes certificate management and enables edge client-certificate validation, consistent routing, and consistent observability. The trade-off is plaintext visibility at the Gateway. If the backend hop must stay encrypted, configure backend TLS as well; private-key exposure and the controller's failure domain also grow.
An interview-quality design is layered: default highly sensitive payment connections to passthrough, while terminating management services that need centralized identity and policy, then protect the second hop with backend TLS.
5. Frontend mTLS and trust anchors
Frontend mTLS validates the client-to-Gateway connection. The Gateway checks the client certificate against configured CA bundles; strict mode accepts only a validated client. An insecure fallback may allow a missing or invalid certificate to reach the backend, so it must be an explicit exception combined with network policy and audit alerts.
Group trust anchors by tenant or environment. Distribute CA bundles through controlled Secret or ConfigMap references. Application teams should not receive platform private-key references. During rotation, publish the new CA, observe a dual-trust window, revoke the old CA, and record activation time and scope.
6. Multi-tenant authorization and conflicts
Listeners on a shared Gateway are a platform boundary. An application should request only approved hostnames and backends. The controller should reject overlapping hostnames, unauthorized parentRefs, cross-namespace backends, and ports or protocols outside policy, and expose the reason in resource status.
Validate ReferenceGrant, Secret references, and GatewayClass capabilities at admission. Review policy changes in Git; at runtime the controller should render configuration only from approved resources. On a route conflict, keep the last known good configuration and report Accepted=False instead of allowing last-writer-wins behavior to silently overwrite another tenant.
7. Failure, upgrade, and observability
Before rollout, verify that the controller supports the stable TLSRoute version, selected TLS mode, client validation, and backend TLS. Gateway API upgrades may require migrating experimental resources to stable v1; replacing a YAML URL alone is insufficient.
Observe SNI matches, listener and route conditions, certificate expiry, client-certificate failure reasons, backend connection errors, configuration propagation latency, and per-tenant handshake and traffic metrics. Keep trust bundles, route state, and backend health checks consistent during failover. If the Gateway is unavailable, define an explicit DNS or load-balancer fallback rather than bypassing it with plaintext traffic.
8. Rubric and follow-ups
Must explain
- Distinguish TLSRoute SNI routing from the key and plaintext boundaries of Passthrough and Terminate.
- Design CA trust, rotation, failure policy, and cross-namespace authorization for frontend mTLS.
- Explain controller capability differences, resource conditions, upgrade migration, and observability instead of only pasting YAML.
Follow-up questions
- If two namespaces claim the same SNI, how do you prevent silent overwrite?
- After the Gateway terminates TLS, how do you guarantee that the second hop remains compliant encryption?
- During client-CA rotation, how do you support dual certificates while bounding the old certificate's maximum lifetime?
Scoring guide
An excellent answer connects resource ownership, encryption boundaries, authorization, and runtime evidence: decide who holds each key, reject conflicts with status conditions, and prove the policy with handshake, certificate, and backend metrics.