From 6aec05deae4f66039119f3fd65f0eaedc2379758 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sun, 30 Aug 2026 15:32:49 +1000 Subject: [PATCH] Disable API token automount on spawned job pods Job pods only need the vault-audience projected token to log in; the default automounted ServiceAccount token hands them the repospawner Role's k8s API access that no job subcommand uses. --- internal/jobs/jobs.go | 3 +++ internal/jobs/jobs_test.go | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/internal/jobs/jobs.go b/internal/jobs/jobs.go index 3af6bd4..86d4f41 100644 --- a/internal/jobs/jobs.go +++ b/internal/jobs/jobs.go @@ -145,6 +145,9 @@ func base(cfg *config.Config, r store.Request, t Type, args []string, deadline i Spec: corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, ServiceAccountName: cfg.JobServiceAccount, + // Jobs never touch the k8s API; only the vault-audience + // projected token below is needed. + AutomountServiceAccountToken: ptr(false), Containers: []corev1.Container{{ Name: string(t), Image: cfg.Image, diff --git a/internal/jobs/jobs_test.go b/internal/jobs/jobs_test.go index 10f5379..b57e46b 100644 --- a/internal/jobs/jobs_test.go +++ b/internal/jobs/jobs_test.go @@ -59,6 +59,10 @@ func TestPRJobSpec(t *testing.T) { if pod.ServiceAccountName != "repospawner" { t.Errorf("serviceAccountName = %q", pod.ServiceAccountName) } + // The job only needs the vault-audience token, not a k8s API token. + if pod.AutomountServiceAccountToken == nil || *pod.AutomountServiceAccountToken { + t.Errorf("automountServiceAccountToken = %v, want false", pod.AutomountServiceAccountToken) + } if len(pod.Containers) != 1 || pod.Containers[0].Image != cfg.Image { t.Fatalf("containers = %+v", pod.Containers) }