github kgateway-dev/kgateway v2.5.0-beta.1

pre-release57 minutes ago

🎉 Welcome to the v2.5.0-beta.1 release of the kgateway project!


Release Notes

Changes since v2.4.0-rc.1

Breaking Changes

  • Route source metadata now uses exactly the original xRoute's rule name for the rule field if available. Otherwise, a generated value that reflects the rule's index in the list of rules is used. Additionally, the originating match's index is added as the match field. (#14522)
  • The deprecated HTTPListenerPolicy CRD has been removed. Migrate to ListenerPolicy by moving the policy spec under spec.default.httpSettings; no fields were renamed or dropped. Migrate before upgrading — the chart upgrade deletes the CRD and Kubernetes garbage-collects any remaining HTTPListenerPolicy objects. See the migration guide: https://github.com/kgateway-dev/kgateway/blob/main/docs/guides/migrating-httplistenerpolicy-to-listenerpolicy.md (#14542)

New Features

  • Added spec.requestMirror to TrafficPolicy. This field allows users to control the Host/:authority header of mirrored requests. disableShadowHostSuffixAppend disables appending -shadow to the end of the Host/:authority header value, and hostRewriteLiteral replaces the mirrored Host/:authority header value with a literal value. (#14441)
  • Add grpcStats to HTTPListenerPolicy to expose Envoy's grpc_stats filter for per-service/method gRPC metrics. (#14452)
  • Added a proxy100Continue field to HTTPSettings on the ListenerPolicy CRD to enable end-to-end proxying of HTTP 1xx informational responses. (#14485)
  • Add BackendConfigPolicy support for separating local-origin outlier detection failures from externally generated errors. (#14486)
  • Added an optional timeout field to RemoteJWKS in the JWT TrafficPolicy to allow users to configure the fetch timeout for remote JWKS servers. (#14501)
  • Add controller.goMemLimitPercent to set GOMEMLIMIT as a percentage of the controller memory limit, disabled by default. (#14537)
  • Add stripTrailingHostDot to ListenerPolicy httpSettings, exposing Envoy's strip_trailing_host_dot so requests with a trailing dot in the Host/authority header can match routes. (#14547)
  • Expose envoy's max_connection_duration via ListenerPolicy and BackendConfigPolicy. (#14559)
  • Add httpUpgrade to TrafficPolicy for configuring HTTP protocol upgrades, including CONNECT termination. (#14587)
  • Added normalizePath and mergeSlashes fields to ListenerPolicy's httpSettings to control whether the HTTP Connection Manager normalizes request paths and merges adjacent slashes. Both default to true, matching prior (hardcoded) behavior. (#14619)
  • Add buffer.filterStage to TrafficPolicy, which moves the buffer filter earlier in the filter chain so that maxRequestSize enforces ahead of filters that read the request body, such as ext_proc. The default placement is unchanged. (#14641)
  • Make controller.goMemLimitPercent track the live container cgroup memory limit, including in-place memory resizes. (#14648)
  • Add validationMode: AllowMissingOrFailed to the JWT GatewayExtension, which verifies JWTs but never rejects a request. Intended for evaluating a JWT policy against live traffic before enforcing it. JWT providers now also record verification failures in the envoy.filters.http.jwt_authn:failed_status dynamic metadata, available to access logs in all validation modes. (#14667)
  • TrafficPolicy rateLimit.local gains an optional shareAcrossGateway field. When true, the token bucket applies to the Gateway as a whole and is divided evenly across its proxy replicas (Envoy local_cluster_rate_limit), so the configured rate no longer scales with the replica count. (#14684)
  • Added clockSkew to GatewayExtension's JWT providers, which sets Envoy's clock_skew_seconds tolerance for the exp and nbf claims. Defaults to Envoy's 60s when unset. (#14686)
  • Added an optional cache field to JWTProvider that enables Envoy's JWT cache for verified tokens. (#14697)

Bug Fixes

  • Fixed policy merging writing merged config back into the source policy's IR on delegated routes. Policies attached to a route delegated by more than one parent could leak config between delegation trees - including ext_authz/ext_proc providers and ACL rules a route never referenced - accumulate config across translation cycles, and produce different data-plane behavior before and after a control-plane restart with no change to the CRs. (#14227)
  • Fixed TrafficPolicy (and other route/listener-attached policy) status incorrectly reporting the wrong Gateway or ListenerSet as ancestor when multiple Gateways/ListenerSets share the same port. (#14448)
  • Fixed a control-plane/data-plane incompatibility during rolling upgrades where proxies still on an older version could have their entire endpoint (EDS) updates withheld, freezing them on stale/deleted backend IPs. (#14472)
  • Honor configured request buffer limits when body transformations are enabled. (#14479)
  • Reduced control-plane memory and GC pressure for endpoint translation at scale by omitting the per-endpoint load-balancing-weight wrapper (Envoy defaults an unset weight to 1) and eliminating dead metadata and re-marshaling allocations on endpoint recomputation. (#14490)
  • fix: Unknown TLS option key and verify_subject_alt_name-without-CA errors now report the actual error in Programmed/Accepted listener conditions instead of misleading "Invalid certificate ref(s)" (#14494)
  • Fixed an issue where a backend whose translation failed (for example, a BackendConfigPolicy
    rejected by strict validation) caused endpoint updates for all other clusters on the same
    gateway to stop flowing until the proxy reconnected. The invalid backend still fails closed;
    unrelated clusters now continue to receive endpoint updates, and the backend's endpoints are
    delivered again once the policy is fixed.
    (#14500)
  • Custom labels set via the Helm chart's commonLabels value now propagate to the kgateway controller's pod template, in addition to the Deployment's own metadata. (#14507)
  • Fixed an issue where a TrafficPolicy using OAuth2 would stay permanently broken if the OpenID provider was unreachable the first time kgateway discovered its configuration, for example when both were restarting together. The discovery failure was latched until the control plane was restarted. kgateway now retries discovery in the background and re-translates affected policies once the provider becomes reachable. Retries start 30 seconds after a failure and back off exponentially, so recovery from a prolonged provider outage can take up to a few minutes. (#14508)
  • Fixed a bug where backends with more than one label produced a different endpoint hash on every recomputation, causing kgateway to publish a new EDS version and push endpoint updates to every connected proxy even when the endpoints had not changed. (#14516)
  • Use the KRT informer cache and keyed status contributions for consistent, resource-local status reconciliation with substantially lower control-plane work at scale. (#14519)
  • Reject unknown KGW_VALIDATOR_MODE values instead of silently falling back to uncached validation. (#14543)
  • xDS client identity (labels/locality/role) is now re-derived on every stream request instead of being frozen at connect time, so proxies that connect during control-plane startup no longer get stuck with an identity computed from stale pod data. (#14582)
  • Fixed an apiKeyAuth TrafficPolicy selecting two Secrets that hold the same api-key value emitting a duplicate credential, which Envoy rejects, freezing xDS delivery for the entire listener while the policy still reported Accepted. Identical credentials are now collapsed, and two clients sharing one key value fail translation with the policy reporting Accepted=False. (#14592)
  • Fixes spurious CDS updates and Envoy cluster re-warming for inline endpoint backends spanning multiple localities. (#14599)
  • Reject ListenerSet attachment when a Gateway's allowedListeners selector cannot be parsed instead of crashing the control plane. (#14626)
  • Fixed AWS Lambda Backends with spec.aws.auth.type: AssumeRole silently ignoring the configured role. The proxy now calls sts:AssumeRole using its ambient credentials (IRSA / EKS Pod Identity / environment) and signs Lambda requests with the returned temporary credentials, instead of signing with the ambient credentials directly. (#14632)
  • The SDS sidecar now binds to 127.0.0.1:8234 by default instead of 0.0.0.0:8234, preventing other pods on the cluster network from reaching the endpoint. Override by setting SDS_SERVER_ADDRESS if the previous behavior is required. (#14638)
  • Update go-control-plane to fix two xDS delivery bugs: a superseded response could be sent to a proxy after it had unsubscribed from those resources (with ordered ADS, the default), and an endpoint watch the control plane could not answer yet was discarded rather than retained, which could leave a proxy on stale endpoints until it reconnected. (#14654)
  • BackendTLSPolicy status now reports an ancestor entry for each target (Service or kgateway Backend) when no route reaches that policy, so policies on unrouted targets — such as a Backend used only by a GatewayExtension — no longer have an empty status. Policies a route reaches are unchanged and continue to report only their Gateway ancestors. (#14659)
  • Fixed GatewayParameters merging so that securityContext.windowsOptions.gmsaCredentialSpecName is preserved instead of being overwritten with the value of gmsaCredentialSpec. (#14660)
  • Bump Envoy to v1.39.1. Fixes Lambda Backends with auth.type: AssumeRole hanging every request when the gateway's base AWS identity is asynchronous (IRSA, EKS Pod Identity). (#14663)
  • A TCPRoute or TLSRoute whose backendRef names a Backend that only works on HTTP routes (dynamicForwardProxy, aws.lambda, gcp) now reports ResolvedRefs=False with reason InvalidKind and routes to the blackhole cluster, instead of programming a cluster that can never carry traffic while reporting success. Backend plugins can declare the route kinds a backend supports via BackendObjectIR.SupportedRouteKinds. (#14734)
  • An AWS Backend whose referenced Secret has an empty accessKey or secretKey is now rejected at translation time and reported on the Backend's Accepted condition, instead of producing an inline credential provider that Envoy rejects (which in the default validation mode discarded the whole CDS update). Error messages now reference the actual Secret data keys (accessKey, secretKey, sessionToken). (#14741)

Cleanup

  • Route matchers using regular expressions no longer set the deprecated google_re2 engine type on the generated Envoy RegexMatcher. RE2 remains the engine Envoy uses, so matching behavior is unchanged. (#14539)
  • Changes default to ordered ADS delivery (the old behavior is achievable with KGW_ENABLE_ORDERED_ADS=false), preserving CDS, EDS, LDS, and RDS response order for same-snapshot busy-stream additions. (#14644)

Dependency Updates

  • Toolchain and dependencies bumped. (#14588)

Contributors

Thanks to all the contributors who made this release possible:

Installation

The kgateway project is available as a Helm chart and docker images.

Helm Charts

The Helm charts are available at:

  • oci://cr.kgateway.dev/kgateway-dev/charts/kgateway
  • oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds

Docker Images

The docker images are available at:

  • cr.kgateway.dev/kgateway-dev/kgateway:v2.5.0-beta.1
  • cr.kgateway.dev/kgateway-dev/sds:v2.5.0-beta.1
  • cr.kgateway.dev/kgateway-dev/envoy-wrapper:v2.5.0-beta.1

Quickstart

Try installing this release:

helm install kgateway-crds oci://cr.kgateway.dev/kgateway-dev/charts/kgateway-crds --version v2.5.0-beta.1 --namespace kgateway-system --create-namespace
helm install kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway --version v2.5.0-beta.1 --namespace kgateway-system --create-namespace

For detailed installation instructions and next steps, please visit our quickstart guide.

Don't miss a new kgateway release

NewReleases is sending notifications on new releases.