agent-platform release v4.28.11

Fixed

  • The agentgateway controller can fetch the models Gateway’s JWKS from the public issuer, and a failed fetch is visible (giantswarm/agent-platform#505; proof 1 of giantswarm/giantswarm#37639). The controller — not the data plane — fetches the JWKS of every AgentgatewayPolicy and pushes the keys to the data plane over xDS; a fetch its network policy denies pushes an empty key set, and every token is refused 401 token uses the unknown key while the data plane has nothing to log. On gazelle the serving slice’s models-jwt policy (JWKS from dex.<installation> on 443, the chart’s default) was served by the platform release’s controller, whose policy admitted the API server, muster and the in-cluster Dex on 5556 and nothing public: error fetching jwks … dial tcp <edge LB>:443: i/o timeout, every id_token refused until the backend was pointed at the in-cluster Dex by hand. Two changes: (1) global.identity.issuerUrl’s host is always an external JWKS target of the controller policy (agent-platform.jwks.issuerTarget, joined into agent-platform.jwks.externalTargets): opened by name on 443 (the URL’s own port when it carries one) behind the DNS proxy clause in the cilium flavour, as port 443 of the wide rule in the kubernetes flavour, in every release that runs the controller and whatever the routes name — the controller serves the JWT policies of every release in the cluster, and the slice’s models policy beside the platform’s release is one the platform’s policy cannot see; an in-cluster issuer adds nothing (gateway.jwksEgress covers it). (2) The controller policies render wherever the controller runs (agent-platform.agentgateway.controller: an agentgateway-* ingress mode, or components.agentgateway on): the serving slice on a workload cluster (components.agentgateway.enabled: true, ingress.mode at its muster-direct default, no edge Gateway) rendered no controller policy at all, though its own controller serves the models Gateway there. The chart’s comments (models-gateway.yaml, the jwks values, gateway.jwksEgress, docs/authentication.md) now name the controller as the fetcher and its egress as the requirement. Visibility: make live-serving-slice NAMESPACE=<the slice's> (tests/verify-serving-slice-live.py) reads the models-jwt policy’s Accepted condition on every ancestor and the controller’s jwks-store entry for the backend’s URL, and fails naming the URL and the controller’s error fetching jwks lines on reason: PartiallyValid or an empty key set — the check the gazelle proof runs before a token is sent. make verify-serving-slice asserts the slice-on-workload-cluster controller policy in both flavours (rendered without an ingress mode; the issuer on 443 with the DNS proxy; an own jwks.host beside it; none beside the platform’s release); make verify-wiring asserts a public issuer is opened from the controller policy with and without a route policy of the release’s own, on the URL’s port, that an in-cluster issuer adds no rule, and holds the all-in-cluster shape byte-identical to origin/main. Every installation with the controller on and a public issuer gets one controller policy change: a toFQDNs rule for the issuer on 443 and the DNS proxy variant of the DNS rule (cilium), or 443 on the wide rule (kubernetes); no pod rolls.