Read-only by default, optional deploy role; no Secrets, exec, port-forward or RBAC. Tokens from kubectl create token, time-limited. Not applied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QLJfZQZeAKAwSqViTmLzki
60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
# Agent access to the mg4 namespace
|
|
|
|
A kubeconfig for a coding agent that reaches **only the `mg4` namespace**, with a token that
|
|
expires on its own. You create and apply everything here yourself; the agent never does.
|
|
|
|
| File | What |
|
|
|---|---|
|
|
| `serviceaccount.yaml` | the `mg4-agent` service account in `mg4`, never mounted into a pod |
|
|
| `role-read.yaml` | read-only: workloads, pods and their logs, services, ConfigMaps, PVCs, events, network policies, IngressRoutes |
|
|
| `role-deploy.yaml` | **optional**: apply this repository's manifests and restart workloads |
|
|
| `make-kubeconfig.sh` | writes the kubeconfig with a time-limited token |
|
|
|
|
Neither role allows **Secrets** (any verb), `pods/exec`, `pods/attach`, `pods/portforward`, RBAC
|
|
objects, the Namespace itself, or anything in another namespace or at cluster scope. The deploy
|
|
role also cannot delete PersistentVolumeClaims, so InfluxDB's data volume stays safe.
|
|
|
|
## 1. Create the service account and its role
|
|
|
|
With your own kubeconfig, after `k8s/` itself is applied (the namespace must exist):
|
|
|
|
```sh
|
|
kubectl apply -k k8s/agent-access/
|
|
```
|
|
|
|
That is read-only. To let the agent also apply changes, uncomment `role-deploy.yaml` in
|
|
`kustomization.yaml` first. Be aware of what that means: whoever may change a Deployment may run
|
|
any image in the namespace, and such a pod could mount mg4's Secrets and print them. Read-only is
|
|
the limit that holds even against a misbehaving agent; the deploy role is a convenience.
|
|
|
|
## 2. Check what it may do
|
|
|
|
```sh
|
|
kubectl auth can-i --list -n mg4 --as=system:serviceaccount:mg4:mg4-agent
|
|
kubectl auth can-i get secrets -n mg4 --as=system:serviceaccount:mg4:mg4-agent # no
|
|
kubectl auth can-i create pods/exec -n mg4 --as=system:serviceaccount:mg4:mg4-agent # no
|
|
kubectl auth can-i list pods -n kube-system --as=system:serviceaccount:mg4:mg4-agent # no
|
|
```
|
|
|
|
## 3. Make the kubeconfig
|
|
|
|
```sh
|
|
k8s/agent-access/make-kubeconfig.sh 24h
|
|
```
|
|
|
|
It takes the API server address and CA from your current context, asks the cluster for a token
|
|
for `mg4-agent` (`kubectl create token`, valid for the duration you give; the API server may cap
|
|
it), and writes `~/.config/nilsmg4/kubeconfig-mg4-agent` with mode 600. The token is never
|
|
printed. The file is outside the repository, so it cannot be committed.
|
|
|
|
Then tell the agent it may use it, e.g. *"you may use ~/.config/nilsmg4/kubeconfig-mg4-agent"*.
|
|
It runs `kubectl` with `KUBECONFIG` pointing at that file, so your own kubeconfig is never used.
|
|
|
|
## Ending access
|
|
|
|
- **Wait:** the token expires after its duration. Run the script again for a new one.
|
|
- **Now:** `kubectl delete serviceaccount mg4-agent -n mg4` invalidates every token made for
|
|
it at once. Remove the rest with `kubectl delete -k k8s/agent-access/`.
|
|
- **Less:** take `role-deploy.yaml` out of the kustomization and
|
|
`kubectl delete rolebinding,role mg4-agent-deploy -n mg4`.
|