Files
cluster-autoscaler-with-capi/.claude/cluster-inspector
kacerrandClaude Opus 5.5 0592608850 Record step 2 of mgmt cluster plan; widen inspector read-only RBAC
Inspector role can now read operator Provider CRs, k3s HelmCharts and nodes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 10:28:30 +02:00
..

cluster-inspector: credentials setup

The cluster-inspector agent (.claude/agents/cluster-inspector.md) only ever talks to clusters through the read-only kubeconfigs in kubeconfigs/ here. They're gitignored and minted by make-kubeconfig.sh from a short-lived ServiceAccount token.

File Purpose
rbac.yaml ServiceAccount kube-system/readonly-inspector + view + read on CAPI CRDs and pod logs (no Secrets)
make-kubeconfig.sh applies RBAC (once), mints a TokenRequest token, writes kubeconfigs/<name>.kubeconfig, runs can-i checks
kubeconfigs/ output, gitignored; one file per cluster, context <name>-ro

1. Management cluster (after phase 1 step 2)

k3s writes server: https://127.0.0.1:6443, so pass the VM address. k3s puts node IPs into the API cert SANs, so the IP works; add --tls-san for a DNS name.

scp ubuntu@<mgmt-vm>:/etc/rancher/k3s/k3s.yaml /tmp/lab-mgmt-admin.yaml   # or use your existing admin kubeconfig
.claude/cluster-inspector/make-kubeconfig.sh lab-mgmt \
  --admin-kubeconfig /tmp/lab-mgmt-admin.yaml \
  --server https://<mgmt-vm-ip>:6443 \
  --apply-rbac
rm /tmp/lab-mgmt-admin.yaml

2. Workload clusters (after phase 1 step 3)

clusterctl get kubeconfig lab1 > /tmp/lab1-admin.yaml     # run against the mgmt cluster (admin)
.claude/cluster-inspector/make-kubeconfig.sh lab1 --admin-kubeconfig /tmp/lab1-admin.yaml --apply-rbac
rm /tmp/lab1-admin.yaml

Expected verification output

  list pods                                     yes
  get machines.cluster.x-k8s.io                 yes    # "no" on workload clusters (no CAPI CRDs), fine
  delete machines.cluster.x-k8s.io              no
  patch machinedeployments.cluster.x-k8s.io     no
  get secrets                                   no

Anything else means the RBAC is wrong. Don't use the agent until it matches.

Refresh / revoke

  • Refresh: re-run the same command without --apply-rbac. The default lifetime is 7 days (--duration); the API server may cap it (--service-account-max-token-expiration).
  • Revoke everything: kubectl delete sa -n kube-system readonly-inspector (as admin). That invalidates every minted token; re-apply rbac.yaml to start over.

RBAC only protects you when the read-only kubeconfig is actually used. Your admin ~/.kube/config is still reachable from any shell. To make Claude Code sessions in this repo default to the read-only files, add this to .claude/settings.local.json (personal, not committed):

{
  "env": {
    "KUBECONFIG": "/Users/jan.novak/srv/go/cluster-autoscaler-with-capi/.claude/cluster-inspector/kubeconfigs/lab-mgmt.kubeconfig:/Users/jan.novak/srv/go/cluster-autoscaler-with-capi/.claude/cluster-inspector/kubeconfigs/lab1.kubeconfig"
  }
}

Then plain kubectl --context lab-mgmt-ro … / --context lab1-ro … works everywhere in the session, and mutations fail on RBAC even if something tries them.