Added
gateway.jwksEgress.external.fqdns,.cidrsand.port(443), in both charts: the destinations the agentgateway controller may reach for a JWKS the routes do not name, and for an issuer reached by address rather than by name.fqdnstakes Cilium FQDN selectors (matchName,matchPattern), read by the cilium flavour and behind the DNS proxy rule its policy renders; the kubernetes flavour selects addresses and never names, so it ignores them.cidrstakes IP blocks of either family in both flavours, and is also the only way to reach what the kubernetes flavour cannot reach by name — its wide rule for a name is0.0.0.0/0and covers public IPv4 only, so a private identity provider insideworldExcludedCIDRsand an issuer resolved over IPv6 belong there. Each list is its own rule on.port, independent ofgateway.jwksEgress.enabled. Both lists are typed: acidrsblock of either family no API server accepts fails the render, and anfqdnsitem is a selector object, never a bare string the Cilium CRD refuses.
Changed
jwtAuthentication.jwks.hostis a hostname, and seven shapes that rendered green now fail the render (#312). Each reached runtime as401 token uses the unknown keyon every request, because the controller fetched no keys: an empty host; an emptyjwks.port, which renders a backend the API server refuses; a host that carries a port (dex.example.com:5556), which belongs injwks.port; an address literal of either family (198.51.100.7,2001:db8::1,1.2.3.999), which the controller cannot select by name — name its blocks ingateway.jwksEgress.external.cidrsinstead; a host that is no hostname, a scheme or the JWKS path glued on (accounts.google.com/keys) and an empty or hyphen-terminated label (a..b.example.com,keys-.example.com) included, where the kubernetes flavour still opened its wide rule and hid the failure; and a host of fewer than three labels (dex,dex.giantswarm,okta.com), which is neither a qualified Service name nor a public issuer — a short Service name resolves through the pod’s search path, which the controller’s egress rule cannot follow. The route subtrees are open objects invalues.schema.json, so these are template guards; each names the value to set. The last one followsnetworkPolicy.enabled: with no policy rendered every destination is reachable and the classification decides nothing.
Fixed
- The agentgateway controller’s network policy reaches every external JWKS host the
jwtAuthenticationroutes name, in both flavours (#312). The controller fetches each policy’s JWKS and pushes the keys to the data plane over xDS, so this is the controller’s egress; the data-plane policies do not change. The policy readskagent.controllerRoute,modelManager.routeandagentManager.route’sjwtAuthentication.jwksand opens each host that is not in-cluster on its own port: atoFQDNsmatchNamein the cilium flavour, an address block minusnetworkPolicy.kubernetes.worldExcludedCIDRsin the kubernetes flavour. The kubernetes flavour selects addresses and never names, so one named external host widens the controller’s egress to every public IPv4 destination on that port, minus the excluded blocks — and only whilenetworkPolicy.kubernetes.apiServerCIDRis a real API-server block, because its default0.0.0.0/0on every port already covers that. An installation that wants it narrow names the issuer’s blocks ingateway.jwksEgress.external.cidrs.gateway.jwksEgress.enabledis now demanded for an in-clusterjwks.hostonly. A host counts as in-cluster when its third dot-separated label issvcand the labels after it are empty,clusterorcluster.local— the forms the pod’s search path produces. A public host that carries ansvclabel elsewhere (a.b.svc.example.com) is external and gets its own rule. Every host is classified and selected in its normalized form — lower case, root dot removed — sodex.giantswarm.svc.cluster.local.names the Service it looks like and no longer widens the controller’s egress to every public destination on the JWKS port. A route whosejwks.portis 443 originates TLS to the issuer withoutjwks.tls.enabled: the port serves no plain HTTP, so the fetch no longer returns no keys. TLS implied by the port verifies againstjwks.tls.caSecretNameor the system trust, neverglobal.identity.ca.secretName: that key is the platform identity provider’s own CA, it signed no public issuer’s certificate, and pinning it would fail the fetch with the same401.jwks.tls.enabled: truenames that provider deliberately and keeps the fallback. No installation needs to act: with in-cluster JWKS hosts only, the whole render is byte-identical to before in both flavours, whichmake verify-wiringasserts againstorigin/main.