paperclip: per-agent kubectl ServiceAccounts + apiserver egress CNP (REN-414) #1080

Merged
Ghost merged 1 commits from atlas/ren-414-agent-kubectl-sa into master 2026-09-30 23:19:33 +00:00

Implements the spec on REN-412 (card REN-414, parent REN-284).

What changed

  • New kubernetes/apps/paperclip/agent-kubectl-rbac.yaml (+ kustomization line):
    • ServiceAccounts paperclip/agent-{atlas,iris,hestia,argus,hermes}, automountServiceAccountToken: false.
    • kubernetes.io/service-account-token Secrets agent-*-token, no data in git (kube-controller-manager fills data.token).
    • ClusterRoleBinding paperclip-agents-view → built-in view for atlas/iris/hestia/argus.
    • RoleBinding monitoring/paperclip-agents-prometheus-read → existing Role paperclip-prometheus-read (unchanged) for the same four.
    • Role + RoleBinding paperclip/agent-token-read: get on the five named token Secrets only, for agent-hermes and the shared paperclip-prometheus-read SA (Hermes still runs in the shared pod).
  • infrastructure/network-policies/paperclip-renner-ns.yaml: CNP paperclip-agents-kube-apiserver — pods with paperclip.io/agent-id in the five ids may egress to entity kube-apiserver on 6443 (CIDR rules do not match node IPs here).

Why

Each agent pod gets its own read-only kubectl identity instead of the shared pod token (REN-412).

Safety

No wildcard, no cluster-admin, no write verb. The readers get exactly what the shared SA holds today; the tokens are worth no more than that, so the shared SA reading them is no escalation. No workload change, nothing restarts. The CNP only adds an allow.

Verified

  • Names do not collide in git; SAs and CNP absent in the cluster (404).
  • Label paperclip.io/agent-id is present on live agent pods in paperclip-renner.
  • Lint only before merge; cluster check after reconcile: each agent-*-token has data.token.

Revert

Revert this commit: Flux prunes the SAs, Secrets (tokens die), bindings and the CNP.

🤖 Generated with Claude Code

Implements the spec on REN-412 (card REN-414, parent REN-284). ## What changed - New `kubernetes/apps/paperclip/agent-kubectl-rbac.yaml` (+ kustomization line): - ServiceAccounts `paperclip/agent-{atlas,iris,hestia,argus,hermes}`, `automountServiceAccountToken: false`. - `kubernetes.io/service-account-token` Secrets `agent-*-token`, no data in git (kube-controller-manager fills `data.token`). - ClusterRoleBinding `paperclip-agents-view` → built-in `view` for atlas/iris/hestia/argus. - RoleBinding `monitoring/paperclip-agents-prometheus-read` → existing Role `paperclip-prometheus-read` (unchanged) for the same four. - Role + RoleBinding `paperclip/agent-token-read`: `get` on the five named token Secrets only, for `agent-hermes` and the shared `paperclip-prometheus-read` SA (Hermes still runs in the shared pod). - `infrastructure/network-policies/paperclip-renner-ns.yaml`: CNP `paperclip-agents-kube-apiserver` — pods with `paperclip.io/agent-id` in the five ids may egress to entity `kube-apiserver` on 6443 (CIDR rules do not match node IPs here). ## Why Each agent pod gets its own read-only kubectl identity instead of the shared pod token (REN-412). ## Safety No wildcard, no cluster-admin, no write verb. The readers get exactly what the shared SA holds today; the tokens are worth no more than that, so the shared SA reading them is no escalation. No workload change, nothing restarts. The CNP only adds an allow. ## Verified - Names do not collide in git; SAs and CNP absent in the cluster (404). - Label `paperclip.io/agent-id` is present on live agent pods in `paperclip-renner`. - Lint only before merge; cluster check after reconcile: each `agent-*-token` has `data.token`. ## Revert Revert this commit: Flux prunes the SAs, Secrets (tokens die), bindings and the CNP. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Ghost added 1 commit 2026-09-30 23:15:03 +00:00
paperclip: per-agent kubectl ServiceAccounts + apiserver egress CNP (REN-414)
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
ci/woodpecker/pr/pr-review Pipeline was successful
0d1181abb1
Five ServiceAccounts agent-{atlas,iris,hestia,argus,hermes} in paperclip
with empty service-account-token Secrets. The four readers get the same
rights they hold today via the shared pod SA: `view` cluster-wide and the
existing monitoring/paperclip-prometheus-read Role. Hermes and the shared
SA get `get` on the five named token Secrets only.

CiliumNetworkPolicy paperclip-renner/paperclip-agents-kube-apiserver lets
the five agents' pods reach the kube-apiserver entity on 6443.

Spec: REN-412. Nothing restarts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
review-bot left a comment
Member

🤖 Automated review — model CLI default (complexity: unknown), commit 0d1181abb146cf658b55c46288f89f6d0853acdb.

Advisory review by the review-bot pipeline. It never approves; a human merges. Push new commits to get a fresh review.


Summary

Adds five per-agent ServiceAccounts (agent-{atlas,iris,hestia,argus,hermes}) with manually-provisioned token Secrets, binds the four non-Hermes agents to the same view ClusterRole + paperclip-prometheus-read Role the shared pod identity already holds, grants a narrow agent-token-read Role/RoleBinding so the shared pod (and agent-hermes) can read the token secrets to mint kubeconfigs, and opens a CiliumNetworkPolicy egress rule from the five labelled agent pods to the kube-apiserver entity on 6443. Pure-RBAC/CNP addition, no workload changes. I checked this against the neighboring RBAC files (prometheus-read-rbac.yaml, cluster-view-rbac.yaml, sandbox-rbac.yaml, paperclip.yaml) and the existing network-policy file it extends, and the change is internally consistent with them — no blocking issues found.

🟡 Suggestions

  • kubernetes/apps/paperclip/agent-kubectl-rbac.yaml:206-214: the agent-token-read RoleBinding grants agent-hermes get on its own token secret and the other four, but nothing currently sets serviceAccountName: agent-hermes on any running pod (Hermes "still runs in the shared pod" per the comment), so this subject is presently inert — consistent with the stated forward-looking intent, just flagging so it isn't mistaken for dead config during a future audit.
  • The PR body's "Verified" section (live-cluster label/name checks, post-reconcile data.token check) is not something this diff-only review can confirm — worth double-checking those manually before/after merge as described, since a typo in one of the five UUIDs in paperclip-agents-kube-apiserver (paperclip-renner-ns.yaml:266-270) would silently leave that agent's egress closed rather than erroring.

Tests

No automated tests are expected or present for this kind of GitOps RBAC/NetworkPolicy manifest addition in this repo (the existing sibling RBAC/CNP files have none either). ci-manifests-test.yml presumably lints/kustomize-builds the tree on this PR, which covers syntax; the PR body's own verification plan (lint pre-merge, data.token populated post-reconcile) is the appropriate functional check for this kind of change.

Recommendation

Looks reasonable — no blocking issues; comments above are optional.

🤖 **Automated review** — model `CLI default` (complexity: unknown), commit `0d1181abb146cf658b55c46288f89f6d0853acdb`. > Advisory review by the `review-bot` pipeline. It never approves; a human merges. Push new commits to get a fresh review. --- ## Summary Adds five per-agent `ServiceAccount`s (`agent-{atlas,iris,hestia,argus,hermes}`) with manually-provisioned token `Secret`s, binds the four non-Hermes agents to the same `view` ClusterRole + `paperclip-prometheus-read` Role the shared pod identity already holds, grants a narrow `agent-token-read` Role/RoleBinding so the shared pod (and `agent-hermes`) can read the token secrets to mint kubeconfigs, and opens a `CiliumNetworkPolicy` egress rule from the five labelled agent pods to the `kube-apiserver` entity on 6443. Pure-RBAC/CNP addition, no workload changes. I checked this against the neighboring RBAC files (`prometheus-read-rbac.yaml`, `cluster-view-rbac.yaml`, `sandbox-rbac.yaml`, `paperclip.yaml`) and the existing network-policy file it extends, and the change is internally consistent with them — no blocking issues found. ## 🟡 Suggestions - `kubernetes/apps/paperclip/agent-kubectl-rbac.yaml:206-214`: the `agent-token-read` RoleBinding grants `agent-hermes` `get` on its own token secret and the other four, but nothing currently sets `serviceAccountName: agent-hermes` on any running pod (Hermes "still runs in the shared pod" per the comment), so this subject is presently inert — consistent with the stated forward-looking intent, just flagging so it isn't mistaken for dead config during a future audit. - The PR body's "Verified" section (live-cluster label/name checks, post-reconcile `data.token` check) is not something this diff-only review can confirm — worth double-checking those manually before/after merge as described, since a typo in one of the five UUIDs in `paperclip-agents-kube-apiserver` (`paperclip-renner-ns.yaml:266-270`) would silently leave that agent's egress closed rather than erroring. ## Tests No automated tests are expected or present for this kind of GitOps RBAC/NetworkPolicy manifest addition in this repo (the existing sibling RBAC/CNP files have none either). `ci-manifests-test.yml` presumably lints/kustomize-builds the tree on this PR, which covers syntax; the PR body's own verification plan (lint pre-merge, `data.token` populated post-reconcile) is the appropriate functional check for this kind of change. ## Recommendation Looks reasonable — no blocking issues; comments above are optional. <!-- pr-review:sha=0d1181abb146cf658b55c46288f89f6d0853acdb -->
Ghost approved these changes 2026-09-30 23:19:33 +00:00
Ghost left a comment

Approved at 0d1181abb1. Checked: diff matches REN-412 spec; CNP agent ids match Paperclip agents; no wildcards/write verbs, secrets get limited by resourceNames; selected pods already have egress policies (paperclip-egress-fqdn), so the CNP only adds an allow; SAs/CNP absent live (404); CI manifests/scripts/pr-review green. Revert: revert the merge.

Approved at 0d1181abb146cf658b55c46288f89f6d0853acdb. Checked: diff matches REN-412 spec; CNP agent ids match Paperclip agents; no wildcards/write verbs, secrets get limited by resourceNames; selected pods already have egress policies (paperclip-egress-fqdn), so the CNP only adds an allow; SAs/CNP absent live (404); CI manifests/scripts/pr-review green. Revert: revert the merge.
Ghost merged commit 7ae8276dea into master 2026-09-30 23:19:33 +00:00
Sign in to join this conversation.