diff --git a/docs/architecture/kubernetes-migration.md b/docs/architecture/kubernetes-migration.md index ffc7cd3d49..08f09d55a6 100644 --- a/docs/architecture/kubernetes-migration.md +++ b/docs/architecture/kubernetes-migration.md @@ -249,10 +249,12 @@ Agent Jobs are built programmatically by ``KubernetesClient.create_container`` ## RBAC Model -The orchestrator uses a ServiceAccount (`egg-orchestrator` in `egg-system`) with two levels of permissions: +The orchestrator uses a ServiceAccount (`egg-orchestrator` in `egg-system`) bound to four namespace- or cluster-scoped roles. There is no broad `egg-orchestrator` ClusterRole — every grant is least-privilege. -1. **ClusterRole** (`egg-orchestrator`): Broad permissions for cross-namespace operations (Jobs, Pods, ConfigMaps) -2. **Role** (`egg-agent-manager` in `egg-agents`): Fine-grained permissions scoped to the agent namespace +1. **Role** (`egg-agent-manager` in `egg-agents`): manage agent Jobs/Pods (`jobs`: create/delete/get/list/watch/patch; `pods`: delete/get/list/watch; `pods/log`: get; `pods/exec`: create). Jobs create their pods on the SA's behalf, so the SA does not need `pods: create`. +2. **Role** (`egg-service-log-reader` in `egg-system`): read the orchestrator's own Deployments and Pod logs (`deployments`: get/list — `list` added in #2648 for `_collect_egg_image_tags`; `pods`: get/list; `pods/log`: get). +3. **ClusterRole** (`egg-cluster-topology-reader`): cluster-scoped `nodes: get/list` for `_detect_k3s`'s kubelet-version probe — the only grant that genuinely needs cluster scope. +4. **Role** (`egg-kube-system-topology-reader` in `kube-system`): `apps/daemonsets: get/list` for `_detect_cni` and `_detect_k3s`'s image-name fallback. Scoped to kube-system to keep cluster-wide DaemonSet reads off the SA (least-privilege per #2658 review). ```yaml # Namespace-scoped Role in egg-agents @@ -267,7 +269,7 @@ rules: verbs: ["create", "delete", "get", "list", "watch", "patch"] - apiGroups: [""] resources: ["pods"] - verbs: ["create", "delete", "get", "list", "watch"] + verbs: ["delete", "get", "list", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get"] @@ -276,7 +278,7 @@ rules: verbs: ["create"] ``` -This replaces the Docker socket mount with a principle-of-least-privilege API access model. The orchestrator can manage Jobs and Pods in `egg-agents` but has no access to other namespaces' workloads. +This replaces the Docker socket mount with a principle-of-least-privilege API access model. The orchestrator can manage Jobs and Pods in `egg-agents`; the topology-reader roles are scoped minimally so `validate_network_isolation` and `get_deployment_context` can detect CNI and k3s state without cluster-wide DaemonSet access. ## Developer Workflow Changes