GEP-5075: Support ClusterTrustBundle as a valid caCertificateRef
(See status definitions.)
1. What
This Gateway Enhancement Proposal (GEP) introduces native support for ClusterTrustBundle resources within Gateway API’s TLS validation fields, specifically targeting caCertificateRefs in both BackendTLSPolicy and Gateway specs. By integrating with certificates.k8s.io cluster-scoped resources, this proposal provides a robust mechanism to distribute and consume platform-managed Certificate Authority (CA) trust anchors.
2. Why
In Kubernetes clusters, validating backend TLS connections or implementing client certificate authentication on ingress listeners requires the validation engine (the Gateway datapath) to reference a trusted set of Certificate Authorities (CAs) - often referred to as trust anchors.
Currently, Gateway API fields like caCertificateRefs (in BackendTLSPolicy and Gateway) only offer “Core” support for local, namespace-scoped ConfigMap resources. Consequently, for cluster-scoped CAs, cluster administrators must replicate CA certificate PEM bundles across all tenant namespaces. This pattern introduces several key operational pain points:
- Administrative Toil: Replicating CA bundles across hundreds of user namespaces requires custom operators, synchronization scripts, or manual intervention, which are fragile and prone to failure.
- Security Risks: Stale CA certificates in outdated namespaces can lead to validation failures, application outages, or accidental trust of insecure endpoints if root rotation is out of sync.
- Consumability Barriers: Application developers should not be responsible for importing, updating, or validating corporate root CAs. They should simply consume a platform-provided, highly available source of trust.
- Control Plane Overhead: Duplicating large
ConfigMapobjects - which can expand to hundreds of kilobytes - across all user namespaces creates significant resource pressure and degrades performance on both etcd and the Kubernetes API server.
With the graduation of ClusterTrustBundle (certificates.k8s.io/v1) to General Availability in Kubernetes 1.37, the platform now provides a native, cluster-scoped container for X.509 trust anchors. Supporting this resource in Gateway API resolves these issues by allowing namespace-scoped resources to safely reference global, cluster-wide trust anchors.
3. Who
Ana (The Application Developer)
- User Story: As Ana, the application developer, I want to reference a pre-existing, platform-managed
ClusterTrustBundlein myBackendTLSPolicyso that my upstream connections validate correctly without requiring local namespace-scoped ConfigMaps.
Chihiro (The Cluster Operator / Platform Engineer)
- User Story: As Chihiro, the cluster operator, I want to deploy a single
ClusterTrustBundleat the cluster level during bootstrap, enabling all tenant namespaces to dynamically and securely resolve valid CAs for TLS handshakes. - User Story: As Chihiro, the cluster operator, I want to configure frontend client certificate validation across multiple Gateway instances referencing a centralized trust anchor, simplifying operational administration for mTLS authentication.
4. Goals and Non-Goals
Goals
- Allow Single ClusterTrustBundle as Source of Truth: Enable using
ClusterTrustBundleas a cluster-scoped source of truth forcaCertificateRefsacross namespaces. - Support Cluster-Scoped Trust Anchor Reference: Allow referencing a
ClusterTrustBundleby name fromBackendTLSPolicyValidationand Gateway frontend TLS validation, using a dedicated cluster-scoped reference type. - Simplify Trust Management: Reduce administrative overhead and avoid synchronization issues by offering native references to cluster-scoped trust anchors.
- Reduce Control Plane Overhead: Avoid duplicating large
ConfigMapobjects—which can expand to hundreds of kilobytes—across user namespaces to prevent resource pressure and performance degradation on etcd and the Kubernetes API server. - Ensure RBAC and Boundary Safety: Leverage
ClusterTrustBundleto provide secure, robust multi-tenant isolation and boundary safety when referencing cluster-scoped trust objects from namespace-scoped policies.
Non-Goals
- Managing Private Keys in a Cluster-Scoped Way:
ClusterTrustBundleobjects carry public certificate PEM blocks only. Private key handling remains strictly in namespace-scopedSecrets. - Defining CA Rotation Engines: This GEP does not prescribe mechanisms for rotating or issuing CA certificates, focusing solely on consumption via API objects.
- Deprecating Namespaced ConfigMaps: We do not propose deprecating or removing support for using namespaced ConfigMaps as
caCertificateRefs.
5. Key Considerations & Guardrails
Feature Support Graduation & Upstream Compliance
To maintain API stability, Gateway API dictates that dependencies on core Kubernetes features must adhere to release-graduation timelines:
- A feature must reside in Kubernetes GA for at least 5 consecutive releases before Gateway API can mandate its support as a Core level feature.
- Because
ClusterTrustBundlegraduates to GA in Kubernetes 1.37, this feature must initially be designated as Extended support. - Gateway implementations running on older cluster versions or environments lacking cluster-scoped lookup engines are not required to implement this GEP to maintain compliance.
RBAC and Namespace Isolation Safety
A key question during community GEP reviews is whether referencing a cluster-scoped resource from a namespace-scoped resource introduces security bypasses or privilege escalation.
- Globally Readable by Design: According to the core Kubernetes API design,
ClusterTrustBundleresources are intended to be globally readable. - Default ServiceAccount Access: Kubernetes grants default read permissions (
get,list,watch) on ClusterTrustBundles to all authenticated users and all ServiceAccounts in the cluster via thesystem:cluster-trust-bundle-discoveryClusterRoleBinding. - Alignment with Security Boundary: Because any pod in a namespace can already read these bundles through standard projected volumes, referencing them in a
BackendTLSPolicyorGatewaylistener does not introduce new attack vectors or leak private data. It aligns perfectly with standard cluster RBAC models. - Hardened Cluster Caveat: Clusters that remove or restrict the default
system:cluster-trust-bundle-discoveryClusterRoleBinding may prevent the Gateway controller’s ServiceAccount from readingClusterTrustBundleresources. Implementations SHOULD document any RBAC prerequisites required for this feature to function.
6. Technical Design & API Changes
This GEP introduces a dedicated ClusterTrustBundleObjectRef type for cluster-scoped ClusterTrustBundle resources and a new optional clusterTrustBundleRef field on the relevant validation structs. Using a named type distinct from LocalObjectReference makes the cluster-scope semantics explicit and avoids ambiguity.
New Type: ClusterTrustBundleObjectRef
// ClusterTrustBundleObjectRef identifies a ClusterTrustBundle.
//
// The Group defaults to "certificates.k8s.io" and the Kind defaults to
// "ClusterTrustBundle", so users only need to specify the name.
type ClusterTrustBundleObjectRef struct {
// Group is the group of the referent.
//
// Defaults to "certificates.k8s.io".
//
// +optional
Group *Group `json:"group,omitempty"`
// Kind is the kind of the referent.
//
// Defaults to "ClusterTrustBundle".
//
// +optional
Kind *Kind `json:"kind,omitempty"`
// Name is the name of the referent.
// +required
Name ObjectName `json:"name"`
}
A ReferenceGrant is not required because ClusterTrustBundle is cluster-scoped and has no target namespace. By default, Kubernetes grants read access to ClusterTrustBundle resources to all authenticated users via the system:cluster-trust-bundle-discovery ClusterRoleBinding.
API Changes
A new optional clusterTrustBundleRef field is added to BackendTLSPolicyValidation and FrontendTLSValidation. The existing caCertificateRefs field is unchanged. Exactly one trust source (caCertificateRefs, clusterTrustBundleRef, or wellKnownCACertificates) may be configured on a given policy.
BackendTLSPolicyValidation (apis/v1/backendtlspolicy_types.go)
type BackendTLSPolicyValidation struct {
// ... existing fields unchanged ...
// ClusterTrustBundleRef is an optional reference to a cluster-scoped
// ClusterTrustBundle (certificates.k8s.io/v1) resource.
//
// Support: Extended
//
// <gateway:experimental>
// +optional
ClusterTrustBundleRef *ClusterTrustBundleObjectRef `json:"clusterTrustBundleRef,omitempty"`
}
The struct-level XValidation rule is updated to accept clusterTrustBundleRef as a valid trust source alongside caCertificateRefs and wellKnownCACertificates.
FrontendTLSValidation (apis/v1/gateway_types.go)
type FrontendTLSValidation struct {
// ... existing fields unchanged ...
// ClusterTrustBundleRef is an optional reference to a cluster-scoped
// ClusterTrustBundle (certificates.k8s.io/v1) resource.
//
// Support: Extended
//
// <gateway:experimental>
// +optional
ClusterTrustBundleRef *ClusterTrustBundleObjectRef `json:"clusterTrustBundleRef,omitempty"`
}
For the Experimental phase, this GEP is intentionally scoped to explicit name-based references to ClusterTrustBundle. Selector-based discovery is out of scope for this proposal.
Example Usage
Cluster-Scoped Trust Anchor Definition
apiVersion: certificates.k8s.io/v1
kind: ClusterTrustBundle
metadata:
name: example.com:internal-signer:v1
spec:
signerName: example.com/internal-signer
trustBundle: |
-----BEGIN CERTIFICATE-----
MIIF6TCCA9GgAwIBAgIURX... (Corporate Root CA)
-----END CERTIFICATE-----
Consumer Policy
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: secure-inventory-validation
namespace: dev-ana
spec:
targetRefs:
- group: ""
kind: Service
name: inventory-db
validation:
hostname: db.internal.example.com
clusterTrustBundleRef:
name: example.com:internal-signer:v1
Support and Validation
ClusterTrustBundle name references via clusterTrustBundleRef have Extended support (Experimental). The existing Core support for a single namespaced ConfigMap via caCertificateRefs remains unchanged.
An implementation that supports this feature MUST:
- Read
ClusterTrustBundle.spec.trustBundlefrom the object named inclusterTrustBundleRefand use its PEM-encoded certificates as trust anchors for the relevant backend or frontend TLS validation. - Treat a nonexistent bundle, an unreadable bundle, a bundle whose
spec.trustBundlecannot be parsed as a CA certificate bundle, or a bundle with an emptyspec.trustBundleas an invalid CA certificate reference. - Set
ResolvedRefs=Falsewith reasonInvalidCACertificateReffor an unresolved or malformed bundle, and MUST NOT use the bundle for TLS validation. - Additionally set
Accepted=Falsewith reasonNoValidCACertificatewhen no valid trust source remains, consistent with the existing contract forBackendTLSPolicyValidationandFrontendTLSValidation. OnBackendTLSPolicyValidationthe trust sources are mutually exclusive, so an invalidclusterTrustBundleRefalways leaves no valid trust source; onFrontendTLSValidationthe bundle supplementscaCertificateRefs, so this applies only when every trust source is invalid. - Fail the data plane for an invalid trust configuration, matching the existing
caCertificateRefscontract: forBackendTLSPolicythe connection to the backend MUST fail and the client MUST receive an HTTP 5xx error response; for Gateway frontend TLS the client connection MUST be rejected during the TLS handshake. - Reconcile updates to the referenced
ClusterTrustBundle, including changes tospec.trustBundle, deletion of the referenced object, and replacement or recreation of an object with the same name. During the interval between deletion and recreation, the implementation MUST treat the reference as invalid and MUST NOT use any previously cached trust anchors. - Not require a
ReferenceGrantfor a validclusterTrustBundleRef.
Implementations that do NOT support this feature MUST set ResolvedRefs=False with reason InvalidKind when clusterTrustBundleRef is specified.
API Availability
ClusterTrustBundle is a core Kubernetes API (certificates.k8s.io/v1, GA in Kubernetes v1.37). On clusters where the API is not available — e.g., Kubernetes versions older than v1.30, or clusters with the ClusterTrustBundle feature gate disabled — implementations MUST:
- Detect availability at startup and at periodic intervals by probing the discovery document (
GET /api) for thecertificates.k8s.iogroup, rather than by issuing client requests that would fail. - Report support dynamically: the
ClusterTrustBundleconformance feature MUST be advertised only when the API is present, so that the reported feature set reflects the cluster, not just the binary. - If a resource with
clusterTrustBundleRefis configured while the API is unavailable, setResolvedRefs=Falsewith reasonInvalidKind(the kind is unresolvable) and, if it is the sole trust source,Accepted=Falsewith reasonNoValidCACertificate. Existing workloads usingcaCertificateRefsMUST continue to function, and the controller MUST NOT crash, fail to start, or drop reconciliation of other resources.
This keeps InvalidKind as the single reason for “kind not available” and InvalidCACertificateRef for “API present but the specific bundle is invalid”, which lets users distinguish a cluster-provisioning problem from a misconfiguration.
7. Conformance
This is an Extended (Experimental) conformance feature.
Feature Names
ClusterTrustBundle— Extended (Experimental) feature indicating support forclusterTrustBundleRef.
This is a single union feature rather than one feature per API, so it belongs to both GatewayExtendedFeatures and BackendTLSPolicyExtendedFeatures. What an implementation must demonstrate follows from the other features it claims:
ClusterTrustBundle+BackendTLSPolicy— MUST supportclusterTrustBundleRefinBackendTLSPolicyValidation.ClusterTrustBundle+GatewayFrontendClientCertificateValidation— MUST supportclusterTrustBundleRefin Gateway frontend TLS validation.
Conformance Tests
| Description | Outcome | Feature |
|---|---|---|
Resolve a named ClusterTrustBundle via clusterTrustBundleRef and use it for backend TLS validation. |
BackendTLSPolicy MUST have ResolvedRefs=True. TLS handshake to backend MUST succeed. |
ClusterTrustBundle + BackendTLSPolicy |
Reference a nonexistent ClusterTrustBundle via clusterTrustBundleRef. |
BackendTLSPolicy MUST have ResolvedRefs=False with reason InvalidCACertificateRef and Accepted=False with reason NoValidCACertificate. TLS handshake MUST fail and the client MUST receive an HTTP 5xx error response. |
ClusterTrustBundle + BackendTLSPolicy |
Configure clusterTrustBundleRef on a cluster where the certificates.k8s.io API is unavailable. |
ResolvedRefs=False with reason InvalidKind MUST be set; other trust sources and unrelated resources MUST continue to be reconciled. |
ClusterTrustBundle + BackendTLSPolicy |
Reference a ClusterTrustBundle with an empty or unparsable spec.trustBundle. |
BackendTLSPolicy MUST have ResolvedRefs=False with reason InvalidCACertificateRef and Accepted=False with reason NoValidCACertificate. TLS handshake MUST fail and the client MUST receive an HTTP 5xx error response. |
ClusterTrustBundle + BackendTLSPolicy |
Update spec.trustBundle of a referenced ClusterTrustBundle. |
Implementation MUST reconcile the change. Effective trust configuration MUST reflect the updated bundle after reconciliation. | ClusterTrustBundle + BackendTLSPolicy |
Delete the referenced ClusterTrustBundle. |
BackendTLSPolicy MUST move to ResolvedRefs=False with reason InvalidCACertificateRef and Accepted=False with reason NoValidCACertificate. Previously established TLS sessions MAY continue but new sessions MUST fail with an HTTP 5xx error response. |
ClusterTrustBundle + BackendTLSPolicy |
Resolve a named ClusterTrustBundle via clusterTrustBundleRef for Gateway frontend client certificate validation. |
All targeted HTTPS listeners MUST have ResolvedRefs=True. Frontend mTLS MUST succeed with a certificate signed by the bundle’s CA. |
ClusterTrustBundle + GatewayFrontendClientCertificateValidation |
8. Alternatives Considered
- Copy the trust bundle to namespaced ConfigMaps. This retains Core support but duplicates data and makes rotation the responsibility of every consuming namespace.
- Reuse
caCertificateRefswithLocalObjectReference. AddingClusterTrustBundleas an acceptedkindin the existingcaCertificateRefsfield avoids adding a new field, butLocalObjectReferencehas no cluster-scope semantics in its name or documentation. Reviewers requested a distinct type name to make cluster-scope intent explicit. - Use selector-based discovery. This could enable dynamic selection of trust bundles, but it introduces additional API surface and requires significantly more specification work around selection semantics, multi-match handling, reconciliation behavior, and conformance. This proposal leaves that to possible future work so the Experimental scope stays focused on explicit name-based references.
- Use
ReferenceGrant.ReferenceGrantexpresses consent by the owner of a target namespace. It cannot apply to a cluster-scoped resource and adds no protection beyond the Kubernetes RBAC already governingClusterTrustBundleaccess.