From 55e80b467cbb929ee7bee052b943cc2e5b9cbca0 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Fri, 3 Jul 2026 23:44:35 +1000 Subject: [PATCH] Add clusterRef to BindTSIGKey TSIG keys were included in every cluster's keys.conf namespace-wide. When multiple clusters share a namespace, that leaks keys across clusters. Add spec.clusterRef so a key can target a specific BindCluster; empty keeps the shared (all-clusters-in-namespace) behaviour. - api: BindTSIGKey.spec.clusterRef (optional) - BindCluster keys.conf now includes only keys with matching or empty clusterRef - regenerate CRDs + install.yaml bundle --- api/v1alpha1/bindtsigkey_types.go | 6 ++++++ config/crd/bases/bind.unkin.net_bindtsigkeys.yaml | 6 ++++++ config/crd/install.yaml | 6 ++++++ internal/controller/bindcluster_controller.go | 10 +++++++++- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/bindtsigkey_types.go b/api/v1alpha1/bindtsigkey_types.go index d454219..aa3f6ea 100644 --- a/api/v1alpha1/bindtsigkey_types.go +++ b/api/v1alpha1/bindtsigkey_types.go @@ -16,6 +16,12 @@ const ( // BindTSIGKeySpec defines a TSIG key. If no existing key material is imported, // the operator generates a random key and stores it in a Secret. type BindTSIGKeySpec struct { + // ClusterRef names the BindCluster this key is included in. When empty the + // key is shared with every cluster in the namespace (useful when multiple + // clusters share one namespace). + // +optional + ClusterRef string `json:"clusterRef,omitempty"` + // Algorithm is the HMAC algorithm. Defaults to hmac-sha256. // +kubebuilder:default="hmac-sha256" // +optional diff --git a/config/crd/bases/bind.unkin.net_bindtsigkeys.yaml b/config/crd/bases/bind.unkin.net_bindtsigkeys.yaml index e51cccc..afdefcb 100644 --- a/config/crd/bases/bind.unkin.net_bindtsigkeys.yaml +++ b/config/crd/bases/bind.unkin.net_bindtsigkeys.yaml @@ -66,6 +66,12 @@ spec: - hmac-sha1 - hmac-md5 type: string + clusterRef: + description: |- + ClusterRef names the BindCluster this key is included in. When empty the + key is shared with every cluster in the namespace (useful when multiple + clusters share one namespace). + type: string importExisting: description: |- ImportExisting, when true, means the referenced Secret already contains a diff --git a/config/crd/install.yaml b/config/crd/install.yaml index aff7be1..469cff2 100644 --- a/config/crd/install.yaml +++ b/config/crd/install.yaml @@ -2043,6 +2043,12 @@ spec: - hmac-sha1 - hmac-md5 type: string + clusterRef: + description: |- + ClusterRef names the BindCluster this key is included in. When empty the + key is shared with every cluster in the namespace (useful when multiple + clusters share one namespace). + type: string importExisting: description: |- ImportExisting, when true, means the referenced Secret already contains a diff --git a/internal/controller/bindcluster_controller.go b/internal/controller/bindcluster_controller.go index 5f379ad..175c4eb 100644 --- a/internal/controller/bindcluster_controller.go +++ b/internal/controller/bindcluster_controller.go @@ -128,7 +128,15 @@ func (r *BindClusterReconciler) reconcileKeysSecret(ctx context.Context, c *bind if err := r.List(ctx, &keys, client.InNamespace(c.Namespace)); err != nil { return err } - items := append([]bindv1alpha1.BindTSIGKey(nil), keys.Items...) + // Include keys scoped to this cluster (spec.clusterRef == name) and shared + // keys (empty clusterRef). This keeps keys from leaking across clusters that + // share a namespace. + var items []bindv1alpha1.BindTSIGKey + for _, k := range keys.Items { + if k.Spec.ClusterRef == "" || k.Spec.ClusterRef == c.Name { + items = append(items, k) + } + } sort.Slice(items, func(i, j int) bool { return items[i].Name < items[j].Name }) var b strings.Builder -- 2.47.3