1. Core API resources
The three resources that form the backbone of every Gateway API deployment. All Standard-channel, all GA since Gateway API v1.0 (October 2023).
| Resource | Channel | Notes | Status |
|---|---|---|---|
GatewayClass |
STANDARD | In use as eg referencing the Envoy Gateway controller. parametersRef points to our EnvoyProxy CR. |
✓ verified |
Gateway |
STANDARD | Live as default/eg. HTTP listener on :80 with allowedRoutes.namespaces.from: All. Has external address 138.124.232.181. |
✓ verified |
HTTPRoute |
STANDARD | Eight live Routes attach to Gateway eg: echo + ui (root + JSON), features (Playground matchers), host-v1 & host-v2 (per-hostname), secret (Basic-Auth), http-to-https-redirect (:80 → :443), plus fortio GRPCRoute and redis TCPRoute. |
✓ verified |
ReferenceGrant |
STANDARD | Live: ReferenceGrant/allow-from-demo in namespace lb-demo lets the features HTTPRoute reach the hello Service across namespaces. Probed by Playground card 13. |
✓ verified |
2. HTTPRoute features
These are typed spec fields on every HTTPRoute. Each replaces an annotation-based hack from the old Ingress days.
| Feature | Channel | Notes | Status |
|---|---|---|---|
| Path · PathPrefix | STANDARD | In use: /demo, /, /features/*. Live on Playground. | ✓ verified |
| Path · Exact | STANDARD | Playground card 1: /features/exact matches, /features/exact/foo does NOT. | ✓ verified |
| Path · RegularExpression | EXPERIMENTAL | Playground card 9: regex ^/features/users/[0-9]+$. Experimental CRDs installed via scripts/10-install-crds.sh. | ✓ verified |
| Hostnames matching | STANDARD | Playground card 10. Two HTTPRoutes (host-v1, host-v2) with different hostnames:. DNS via external-dns. | ✓ verified |
| Header matching | STANDARD | Playground card 3: x-canary: yes routes to echo-v2. | ✓ verified |
| Method matching | STANDARD | Playground card 2: POST gets the POST-only rule, GET falls through to the fallback. | ✓ verified |
| Query-param matching | STANDARD | Playground card 4: ?canary=true routes to echo-v2. | ✓ verified |
| Traffic splitting (weights) | STANDARD | Playground card 5: 80/20 split. The probe fires 20 requests and shows the observed distribution as a chart. | ✓ verified |
| Filter · RequestHeaderModifier | STANDARD | Playground card 7: Gateway injects x-injected-by-gateway and x-trace-id into the request, backend echoes them. | ✓ verified |
| Filter · ResponseHeaderModifier | STANDARD | Used by every Playground card (sets x-gw-matched). Card 11 demonstrates add/set/remove explicitly. | ✓ verified |
| Filter · URLRewrite | STANDARD | Playground card 6: /features/rewrite/foo rewritten to /rewritten/foo before reaching the backend. | ✓ verified |
| Filter · RequestRedirect | STANDARD | Two live uses: Playground card 8 (path redirect 302) and the cluster-wide HTTP→HTTPS redirect on the :80 listener (301). | ✓ verified |
| Filter · RequestMirror | STANDARD | Playground card 12: primary echo, mirror echo-v2. Mirror is fire-and-forget, so the browser only sees the primary's response. | ✓ verified |
| Filter · ExtensionRef | STANDARD | Hook for implementation-specific filters (EG plugins). | not tested |
| Cross-namespace backendRef | STANDARD | Playground card 13: HTTPRoute in demo targets lb-demo/hello; ReferenceGrant in lb-demo authorises it. | ✓ verified |
| Backend timeouts | STANDARD | Playground card 14: timeouts.request: 2s in front of an httpbin /delay/5 backend. Gateway returns 504 in ~2s. | ✓ verified |
| Session persistence | EXPERIMENTAL | Cookie / header sticky sessions on backendRef. | not tested |
| BackendRef percentage mirror | EXPERIMENTAL | Mirror a fraction (e.g. 10%) of traffic. | not tested |
3. Beyond HTTPRoute — other Route kinds
Gateway API can route more than HTTP. These are separate Route kinds
used the same way (attach to a Gateway, target backend
Services). All require installing the Experimental
channel CRDs.
| Route Kind | Channel | Notes | Status |
|---|---|---|---|
GRPCRoute | STANDARD | Live on grpc.wolfslight.cc (own cert + listener). Fortio gRPC server behind it. Playground card 16 + grpcurl example. | ✓ verified |
TLSRoute | EXPERIMENTAL | CRDs installed. TLS passthrough by SNI. Would need a separate port (e.g. :8443) since :443 is in TLS-Terminate mode. | not tested |
TCPRoute | EXPERIMENTAL | Live on Gateway port :6379 → Redis Pod (capped at 8 MB). Playground card 17. Test with redis-cli -h gateway.wolfslight.cc -p 6379 PING. | ✓ verified |
UDPRoute | EXPERIMENTAL | CRDs installed. Would need a UDP backend (e.g. CoreDNS) on a fresh port. | not tested |
4. Gateway listener features
What you can configure on a Gateway itself — listeners,
TLS, infrastructure params, address types.
| Feature | Channel | Notes | Status |
|---|---|---|---|
| HTTP listener (port 80) | STANDARD | Live as name: http on Gateway eg. Currently runs only the HTTP→HTTPS redirect route. | ✓ verified |
| HTTPS listener (port 443) | STANDARD | Four live HTTPS listeners (https-gateway, https-v1-features, https-v2-features, https-grpc), each with its own cert-manager-issued Let's Encrypt cert. | ✓ verified |
| TLS Passthrough listener | EXPERIMENTAL | Listener mode for TLSRoute. Would conflict with our HTTPS Terminate listener on :443 — requires a separate port. | not tested |
| Multiple listeners | STANDARD | Six listeners live on Gateway eg: 1× HTTP :80, 4× HTTPS :443 (SNI dispatch: gateway, v1.features, v2.features, grpc) and 1× TCP tcp-redis :6379. | ✓ verified |
allowedRoutes.namespaces | STANDARD | Verified: routes in demo attach to Gateway in default via from: All. | ✓ verified |
allowedRoutes.kinds | STANDARD | Restrict which Route kinds may attach. | available |
| Hostname on listener | STANDARD | Live: each HTTPS listener has a single hostname: (gateway., v1.features., v2.features.) — Envoy uses SNI to pick the right cert. | ✓ verified |
parametersRef (GatewayClass) | STANDARD | Verified: our GatewayClass eg references the EnvoyProxy CR cce-proxy-config with the CCE-specific ELB annotations. | ✓ verified |
parentRef.sectionName | STANDARD | Used to pin routes to specific listeners: HTTPRoute echo→https-gateway, host-v1→https-v1-features, http-to-https-redirect→http. | ✓ verified |
tls.certificateRefs | STANDARD | Per-listener Secret reference. Four separate Secrets, one per hostname (managed by cert-manager). | ✓ verified |
Gateway.spec.infrastructure | STANDARD | Annotation/label propagation to underlying infra. EG supports. | available |
Gateway.spec.addresses | STANDARD | Request a specific IP. Not used (we let CCE allocate). | not tested |
5. Envoy Gateway extensions (beyond the spec)
Envoy Gateway ships additional CRDs under gateway.envoyproxy.io
for features the Gateway API spec doesn't yet cover — but in a
Gateway-API-shaped way (typed, declarative, RBAC-able).
| Resource | Channel | Notes | Status |
|---|---|---|---|
EnvoyProxy | EG-EXTENSION | Per-GatewayClass data-plane config. We use it to inject CCE ELB annotations. | ✓ verified |
BackendTrafficPolicy | EG-EXTENSION | Two policies live: ratelimit-features (10 rps per IP) and ratelimit-echo (20 rps). Local rate-limit, no Redis. Playground card 18. | ✓ verified |
ClientTrafficPolicy | EG-EXTENSION | Live as tls-min-1-2 on the Gateway — enforces TLS ≥ 1.2 and only AEAD ciphers (GCM, ChaCha20-Poly1305). | ✓ verified |
SecurityPolicy | EG-EXTENSION | Three policies live: secret-basic-auth (Basic Auth on /secret), cors-features (CORS allowlist for HTTPRoute) and cors-grpc (CORS for the fortio GRPCRoute — kind-agnostic CRD). Same CRD covers JWT, OIDC, ext-auth, API-key. | ✓ verified |
EnvoyExtensionPolicy | EG-EXTENSION | Live as coraza-waf in demo NS — Coraza WAF as a WASM filter, OWASP-style rules (SQLi, XSS, traversal, RFI, scanner-UA all return 403). Playground card 20. | ✓ verified |
EnvoyPatchPolicy | EG-EXTENSION | Direct xDS-resource patching as escape hatch. | not tested |
HTTPRouteFilter | EG-EXTENSION | EG-specific HTTPRoute filters (CredentialInjection, etc). | not tested |
Backend | EG-EXTENSION | Reference non-Service backends (IP, FQDN, Unix socket). | not tested |
5b. Hardening · OWASP-style protection
Defense-in-depth at the gateway layer — what's live in front of every
request to gateway.wolfslight.cc.
| Layer | Implemented as | Notes | Status |
|---|---|---|---|
| TLS hardening (min v1.2, AEAD ciphers) | ClientTrafficPolicy | Blocks TLS 1.0/1.1, RC4, 3DES, all CBC modes. Only ECDHE + AES-GCM / ChaCha20-Poly1305. | ✓ verified |
| Rate limiting (10 rps/IP) | BackendTrafficPolicy | Local (per Envoy pod), no Redis. Playground card 18 fires 20 parallel and shows the 10/10 split. | ✓ verified |
| CORS allowlist | SecurityPolicy | Explicit origins (gateway / v1.features / v2.features), no *. Methods + headers list. |
✓ verified |
| Security headers | HTTPRoute filter | HSTS, X-Frame-Options DENY, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, CSP — applied on every UI + JSON + Secret response. Playground card 19. | ✓ verified |
| Basic-Auth gate | SecurityPolicy | Protects /secret with htpasswd Secret (SHA-1). 401 without creds, 200 with test:test. Playground card 15. |
✓ verified |
| WAF — OWASP-style rules | EnvoyExtensionPolicy (WASM) | Coraza WAF — ModSecurity-compatible rule engine running as Envoy WASM filter. Blocks SQL-injection, XSS, path traversal, command injection, RFI, scanner User-Agents. Playground card 20. | ✓ verified |
| HTTP → HTTPS redirect | HTTPRoute filter | 301 on :80 via RequestRedirect filter pinned to sectionName: http. |
✓ verified |
| JWT / OIDC / ext-auth | SecurityPolicy | Same CRD as Basic-Auth, different sub-blocks. Not built but trivially addable. | available |
| Global rate-limit (Redis-backed) | BackendTrafficPolicy.rateLimit.global | Cluster-wide consistent limits across many Envoy pods. Local rate-limit covers the demo. | available |
| mTLS to backends | BackendTLSPolicy / BackendTrafficPolicy.tls | Encrypt the leg between Envoy and backend pods. Not exercised here. | not tested |
6. Swiss OTC / CCE-specific findings
These are behaviours of the underlying cloud + CCM, not of Gateway API
itself — but they show up exactly because Gateway API needs them. From
the live runs documented in docs/compatibility-matrix.md.
| Concern | Layer | Notes | Status |
|---|---|---|---|
| ELB auto-provisioning | CCE-CCM | Servicetype=LoadBalancer + elb.autocreate triggers ELB+EIP in ~15 s. Three ELBs running in parallel right now. | ✓ verified |
| EIP automatic attachment | CCE-CCM | CCM creates an EIP and binds it to the new ELB. UUIDs written back as kubernetes.io/elb.eip-id annotation. | ✓ verified |
Strict bandwidth_name | CCE-CCM | Admission webhook rejects autocreate JSON without bandwidth_name: "elb autoCreate field:[bandwidth_name] is invalid". Repo's manifests include it. | ✓ verified |
| Source-IP preservation | CCE-CCM | EG defaults Envoy data-plane Service to externalTrafficPolicy: Local. Real client IP shows up in X-Forwarded-For. | ✓ verified |
| TLS termination at Envoy (not the ELB) | CCE-CCM + EG | L4 ELB passes TCP through unchanged; Envoy data-plane terminates TLS using cert-manager-issued certs. Four concurrent HTTPS listeners with SNI dispatch. | ✓ verified |
| DNS via Cloudflare (manual script) | cluster-external | Initial three A-records (gateway/lb/whoami) managed by scripts/90-dns.sh. Superseded for the gateway-side by external-dns. | ✓ verified |
| DNS via external-dns (auto) | cluster-external | external-dns watches Services + HTTPRoute hostnames, syncs to Cloudflare every 30 s. Live: v1.features., v2.features. appeared automatically. RFC1918 IPs filtered via --exclude-target-net. | ✓ verified |
| cert-manager + Let's Encrypt (DNS-01) | cluster-external | ClusterIssuer letsencrypt-prod with Cloudflare DNS-01 solver. Four live certs (per-hostname, no wildcard) — auto-renewal 60 days before expiry. | ✓ verified |
| HTTP → HTTPS redirect | EG | One HTTPRoute pinned to the :80 listener via sectionName: http + RequestRedirect filter. 301 for every request. | ✓ verified |
Shared-ELB pattern (elb.id) | CCE-CCM | whoami + fortune share one ELB: whoami's Service has elb.autocreate, fortune's references the resulting elb.id with a different listener port. Same EIP 138.124.232.13. | ✓ verified |
| Multiple Gateways → multiple ELBs | CCE-CCM | Gateway-API-ELB + Direct-LB-Demo + Shared-ELB run side-by-side. Three independent EIPs, three independent backend pools. | ✓ verified |
| SWR mirror quirks | CCE-image-pull | Swiss OTC's SWR mirror returns 401 for some library/* images (observed: library/kong). Workaround: use namespaced image (kong/kong). | ✓ verified |
7. Upstream conformance suite
The authoritative "does X support Gateway API properly" answer comes from the upstream conformance suite — a Go test binary that exercises every spec'd feature against a real cluster + controller and emits a report.
| Profile / suite | Channel | Notes | Status |
|---|---|---|---|
| Conformance Profile: Gateway-HTTP | STANDARD | Tests the GA HTTPRoute surface. Runner instructions at tests/conformance/README.md; takes ~30–60 min. | not tested |
| Conformance Profile: Gateway-GRPC | STANDARD | Tests GRPCRoute surface. | not tested |
| Conformance Profile: Gateway-TLS | EXPERIMENTAL | Tests TLSRoute and TLS termination. | not tested |
| Conformance Profile: Mesh | STANDARD | For service-mesh implementations (not our use case). | n/a |
How to run it (~30–60 min)
Clones the Gateway API repo at the right tag and runs the conformance test binary against this cluster's eg GatewayClass:
git clone --depth 1 --branch v1.2.1 \ https://github.com/kubernetes-sigs/gateway-api.git /tmp/gateway-api cd /tmp/gateway-api go test ./conformance \ -run TestConformance -v -timeout 60m \ -args --gateway-class=eg --report-output=$PWD/conformance-report.yaml
Output: conformance-report.yaml with a per-test pass/fail/skip matrix. The "fail" lines are the actual "improperly supported" cells. Full instructions in tests/conformance/README.md.
8. Verdict
What's still on the "not tested" list — and what it would take to flip those rows to green.
| Category | Why it's not here yet | How to enable |
|---|---|---|
| TLSRoute / TCPRoute / UDPRoute | CRDs are installed (experimental channel is live), but each needs its own listener at a fresh port + a backend speaking the right protocol. | Add e.g. name: tcp listener on port 9000, deploy a TCP backend, write a TCPRoute. TLSRoute conflicts with our HTTPS Terminate :443 — needs a separate port like 8443. |
| Session persistence + BackendRef percentage mirror | Experimental-channel HTTPRoute fields. CRDs present but unused so far. | Add spec.rules[].sessionPersistence or filters: [{type: RequestMirror, requestMirror.percent: 10}] to a route. |
| Other EG extensions (BackendTrafficPolicy, ClientTrafficPolicy, EnvoyExtensionPolicy, EnvoyPatchPolicy, HTTPRouteFilter, Backend) | CRDs installed by Envoy Gateway, no demo using them yet. SecurityPolicy was the first one — same pattern applies. | Pick one per use case: BackendTrafficPolicy for retries/circuit-breaking, ClientTrafficPolicy for HTTP/2-3 tuning, etc. Each is a Gateway-API-shaped CRD with targetRefs. |
| Conformance suite output | ~30–60 min run in a sandbox namespace. Authoritative pass/fail report. | Follow tests/conformance/README.md. Paste the resulting conformance-report.yaml summary into docs/compatibility-matrix.md. |
Net: this cluster supports Gateway API correctly
43 of 52 features audited above are live-verified on this cluster: the full HTTPRoute matcher + filter surface, all Standard-channel Gateway listener features (HTTP + HTTPS + multi- listener SNI + per-route sectionName binding), GRPCRoute + TCPRoute at separate ports, three distinct ELB patterns (autocreate, elb.id reuse, multi-Gateway), auto-DNS via external-dns and auto-TLS via cert-manager + Let's Encrypt DNS-01, and seven concurrent EG- Extension policies for hardening (TLS-min, rate-limit, CORS, Basic-Auth, security-headers, Coraza WAF with OWASP-style rules, HTTP→HTTPS redirect).
The remaining "not tested" rows are not failures — they're features the spec describes that we simply haven't built a demo for yet (TLSRoute / UDPRoute at separate ports, sticky sessions, mTLS to backends, global rate-limit, JWT/OIDC). Zero features are confirmed broken on CCE.