From 191eb91642de7bd9e1f3aab08f6a8061117be08b Mon Sep 17 00:00:00 2001 From: Andrew Stoltz <1578013+astoltz@users.noreply.github.com> Date: Wed, 17 Jun 2026 11:28:19 -0500 Subject: [PATCH] security(agent-zero): replace cluster-admin with least-privilege read-only RBAC (SEC-6/RBAC-001) agent-zero is an LLM agent; cluster-admin let raw kubectl bypass the MCP layer to read every Secret / exec any pod. Swap for a read-only ClusterRole (no secrets/ configmaps/exec/writes) so sensitive + mutating actions go through gated MCP tools. Already applied live + verified (secrets/exec/write -> Forbidden, observe stays); this makes it durable so ArgoCD selfHeal doesn't revert to cluster-admin. Co-Authored-By: Claude Opus 4.8 --- apps/agent-zero/agent-zero.yaml | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/apps/agent-zero/agent-zero.yaml b/apps/agent-zero/agent-zero.yaml index 7228981..f1206cb 100644 --- a/apps/agent-zero/agent-zero.yaml +++ b/apps/agent-zero/agent-zero.yaml @@ -76,14 +76,47 @@ metadata: namespace: agent-zero --- +# SEC-6 / audit RBAC-001: agent-zero is an LLM agent — cluster-admin let raw +# kubectl BYPASS the MCP layer to read every Secret / exec any pod. Scoped to +# read-only (no secrets/configmaps/exec/writes) so sensitive + mutating actions +# must go through the gated MCP tools (the operator's intended boundary). +# Detail: FlowerCore.Notes docs/security/sec-6-agent-zero-rbac-remediation.md. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: agent-zero-readonly + labels: + flowercore.io/sec-lane: SEC-6 +rules: + - apiGroups: [""] + resources: ["pods", "pods/log", "services", "endpoints", "events", "namespaces", "nodes", "persistentvolumeclaims", "replicationcontrollers", "serviceaccounts"] + verbs: ["get", "list", "watch"] + - apiGroups: ["apps"] + resources: ["deployments", "replicasets", "statefulsets", "daemonsets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["batch"] + resources: ["jobs", "cronjobs"] + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses", "networkpolicies"] + verbs: ["get", "list", "watch"] + - apiGroups: ["traefik.io", "traefik.containo.us"] + resources: ["ingressroutes", "middlewares"] + verbs: ["get", "list", "watch"] + - apiGroups: ["metrics.k8s.io"] + resources: ["pods", "nodes"] + verbs: ["get", "list"] +--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: agent-zero-cluster-admin + name: agent-zero-readonly + labels: + flowercore.io/sec-lane: SEC-6 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: cluster-admin + name: agent-zero-readonly subjects: - kind: ServiceAccount name: agent-zero