security(agent-zero): remove cluster RBAC entirely + no token mount (operator directive — MCP only)
Operator: agent-zero must reach the cluster ONLY through gated MCP tools, not a service account with cluster roles for raw kubectl. Removed the read-only ClusterRole/ClusterRoleBinding entirely (SA now has zero cluster perms) and set automountServiceAccountToken: false so no K8s API token is mounted at all. Applied live (SA secrets/exec/pods/namespaces -> all Forbidden); this makes it durable so ArgoCD selfHeal won't re-create any role. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -75,52 +75,12 @@ metadata:
|
||||
name: agent-zero
|
||||
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).
|
||||
# SEC-6 / audit RBAC-001 (operator directive 2026-06-17): agent-zero is an LLM
|
||||
# agent and must reach the cluster ONLY through gated MCP tools — NOT raw kubectl.
|
||||
# It therefore has NO ClusterRole/ClusterRoleBinding at all, and the pod sets
|
||||
# automountServiceAccountToken: false (below) so no Kubernetes API token is even
|
||||
# mounted. History: cluster-admin -> read-only -> (now) no cluster RBAC / no token.
|
||||
# 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-readonly
|
||||
labels:
|
||||
flowercore.io/sec-lane: SEC-6
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: agent-zero-readonly
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: agent-zero
|
||||
namespace: agent-zero
|
||||
|
||||
# =============================================================================
|
||||
# Agent Zero — AI Agent Web UI (NUC Edition, Blue Jay Profile)
|
||||
@@ -222,6 +182,9 @@ spec:
|
||||
app: agent-zero
|
||||
spec:
|
||||
serviceAccountName: agent-zero
|
||||
# SEC-6: no Kubernetes API token mounted — agent-zero reaches the cluster
|
||||
# only via gated MCP tools, never raw kubectl. (RBAC is also removed above.)
|
||||
automountServiceAccountToken: false
|
||||
initContainers:
|
||||
# Wait for fc-llm-bridge to be reachable before starting Agent Zero.
|
||||
- name: wait-for-llm-bridge
|
||||
|
||||
Reference in New Issue
Block a user