From f1c3b9617f7dcc4ef588193cd0670c952321bb27 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sun, 2 Aug 2026 21:49:37 +1000 Subject: [PATCH] Add agent-dns RBAC: static SA + ClusterRole + per-namespace RoleBindings (#332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why Vault's kubernetes secret engine will mint scoped tokens for a static \`agent-dns\` service account instead of generating cluster-wide RBAC, so agent DNS access is confined to exactly the bind namespaces. This is the GitOps half of the terraform-vault agent-dns role rework (PR unkin/terraform-vault#109). Ordering: this must sync before the Vault \`agent-dns\` creds are usable — Vault mints tokens for an SA that must already exist. ## How - Add ServiceAccount \`agent-dns\` + ClusterRole \`agent-dns\` (definition only, no ClusterRoleBinding) in \`bind-system\`: full verbs on \`bind.unkin.net\` CRDs, get/list/watch pods/services/configmaps/events, get pods/log. - Add RoleBinding \`agent-dns\` in each of \`bind-system\`, \`bind-internal\`, \`bind-external\`, \`externaldns\`, binding the SA to the ClusterRole in that namespace — confining all access (reads included) to those four namespaces. Whitelist note: the platform AppProject already permits ClusterRole/ClusterRoleBinding and all four namespace destinations, so no project change is needed. https://claude.ai/code/session_01JUoARVdmhxKQHyyyp1pxeT --------- Co-authored-by: Ben Vincent Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/332 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- .../bind-external/agent-dns-rolebinding.yaml | 16 ++++++++ apps/base/bind-external/kustomization.yaml | 1 + .../bind-internal/agent-dns-rolebinding.yaml | 16 ++++++++ apps/base/bind-internal/kustomization.yaml | 1 + apps/base/bind-system/agent-dns-rbac.yaml | 38 +++++++++++++++++++ apps/base/bind-system/kustomization.yaml | 1 + .../externaldns/agent-dns-rolebinding.yaml | 16 ++++++++ apps/base/externaldns/kustomization.yaml | 1 + 8 files changed, 90 insertions(+) create mode 100644 apps/base/bind-external/agent-dns-rolebinding.yaml create mode 100644 apps/base/bind-internal/agent-dns-rolebinding.yaml create mode 100644 apps/base/bind-system/agent-dns-rbac.yaml create mode 100644 apps/base/externaldns/agent-dns-rolebinding.yaml diff --git a/apps/base/bind-external/agent-dns-rolebinding.yaml b/apps/base/bind-external/agent-dns-rolebinding.yaml new file mode 100644 index 0000000..7a7ffb6 --- /dev/null +++ b/apps/base/bind-external/agent-dns-rolebinding.yaml @@ -0,0 +1,16 @@ +--- +# Confines the agent-dns service account (in bind-system) to the agent-dns +# ClusterRole within this namespace. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-dns + namespace: bind-external +subjects: + - kind: ServiceAccount + name: agent-dns + namespace: bind-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: agent-dns diff --git a/apps/base/bind-external/kustomization.yaml b/apps/base/bind-external/kustomization.yaml index de5a685..1e3ed86 100644 --- a/apps/base/bind-external/kustomization.yaml +++ b/apps/base/bind-external/kustomization.yaml @@ -7,3 +7,4 @@ resources: - cluster.yaml - tsigkey.yaml - zones.yaml + - agent-dns-rolebinding.yaml diff --git a/apps/base/bind-internal/agent-dns-rolebinding.yaml b/apps/base/bind-internal/agent-dns-rolebinding.yaml new file mode 100644 index 0000000..6704086 --- /dev/null +++ b/apps/base/bind-internal/agent-dns-rolebinding.yaml @@ -0,0 +1,16 @@ +--- +# Confines the agent-dns service account (in bind-system) to the agent-dns +# ClusterRole within this namespace. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-dns + namespace: bind-internal +subjects: + - kind: ServiceAccount + name: agent-dns + namespace: bind-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: agent-dns diff --git a/apps/base/bind-internal/kustomization.yaml b/apps/base/bind-internal/kustomization.yaml index 112b5d8..d2f50fb 100644 --- a/apps/base/bind-internal/kustomization.yaml +++ b/apps/base/bind-internal/kustomization.yaml @@ -8,3 +8,4 @@ resources: - resolvers - externaldns - tsig-api + - agent-dns-rolebinding.yaml diff --git a/apps/base/bind-system/agent-dns-rbac.yaml b/apps/base/bind-system/agent-dns-rbac.yaml new file mode 100644 index 0000000..c5db3d1 --- /dev/null +++ b/apps/base/bind-system/agent-dns-rbac.yaml @@ -0,0 +1,38 @@ +--- +# Static service account that Vault's kubernetes secret engine mints scoped +# tokens for (agent-dns role). RBAC is confined to the bind namespaces via the +# per-namespace RoleBindings below, not a ClusterRoleBinding. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: agent-dns + namespace: bind-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: agent-dns +rules: + - apiGroups: ["bind.unkin.net"] + resources: ["*"] + verbs: ["*"] + - apiGroups: [""] + resources: ["pods", "services", "configmaps", "events"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods/log"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-dns + namespace: bind-system +subjects: + - kind: ServiceAccount + name: agent-dns + namespace: bind-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: agent-dns diff --git a/apps/base/bind-system/kustomization.yaml b/apps/base/bind-system/kustomization.yaml index 453e5d6..3562333 100644 --- a/apps/base/bind-system/kustomization.yaml +++ b/apps/base/bind-system/kustomization.yaml @@ -8,5 +8,6 @@ resources: # vendored here, so they never drift from the operator. - https://git.unkin.net/unkin/bind-operator/raw/tag/v0.2.6/config/crd/install.yaml - rbac.yaml + - agent-dns-rbac.yaml - deployment.yaml - vpa.yaml diff --git a/apps/base/externaldns/agent-dns-rolebinding.yaml b/apps/base/externaldns/agent-dns-rolebinding.yaml new file mode 100644 index 0000000..a15bd7d --- /dev/null +++ b/apps/base/externaldns/agent-dns-rolebinding.yaml @@ -0,0 +1,16 @@ +--- +# Confines the agent-dns service account (in bind-system) to the agent-dns +# ClusterRole within this namespace. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-dns + namespace: externaldns +subjects: + - kind: ServiceAccount + name: agent-dns + namespace: bind-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: agent-dns diff --git a/apps/base/externaldns/kustomization.yaml b/apps/base/externaldns/kustomization.yaml index cc622a0..08ca6ac 100644 --- a/apps/base/externaldns/kustomization.yaml +++ b/apps/base/externaldns/kustomization.yaml @@ -6,3 +6,4 @@ resources: - namespace.yaml - vaultauth.yaml - vaultstaticsecret.yaml + - agent-dns-rolebinding.yaml