Skip to content

executor/k8s: create a dedicated ServiceAccount for job pods - #951

Open
marcleblanc2 wants to merge 2 commits into
mainfrom
marc/executor-job-service-account
Open

marcleblanc2 wants to merge 2 commits into
mainfrom
marc/executor-job-service-account

Conversation

@marcleblanc2

@marcleblanc2 marcleblanc2 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Paired with sourcegraph/sourcegraph#16392

  • Job pods spawned by the Kubernetes executor run as the namespace's default ServiceAccount, with its token automounted, so they share an identity with other workloads in the namespace
    • In a stock charts/sourcegraph deployment: gitserver, searcher, indexed-search, blobstore, redis, the code intel workers, syntect-server, and the OTel and node-exporter pods
  • This blocks identity-based policy (NetworkPolicy by ServiceAccount, Istio AuthorizationPolicy) on the job pods, and hands untrusted batch change / auto-indexing code a Kubernetes API token it shouldn't have

This change:

  • Adds executor.kubernetesJob.serviceAccount.{create,name,annotations,automountToken} values
  • Renders a sg-executor-job ServiceAccount by default, with no RBAC bindings and automountServiceAccountToken: false on the ServiceAccount object itself, so even executor images that predate sourcegraph/sourcegraph#16392 stop mounting the token once they run as this SA
  • Passes KUBERNETES_JOB_SERVICE_ACCOUNT_NAME and KUBERNETES_JOB_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN through the executor ConfigMap
    • Executors that predate the sourcegraph PR ignore both keys, so their job pods keep running as default until the image is upgraded

Design notes:

  • The ServiceAccount is gated on executor.configureRbac as well as serviceAccount.create, matching sg-executor and its Role/RoleBinding
  • A second executor release in the same namespace (for example batches next to codeintel) already sets configureRbac: false and will not fight over ownership of the SA
  • The SA is created in executor.namespace (explicit metadata.namespace), since a pod can only reference a ServiceAccount in its own namespace
    • Note: The existing sg-executor Role and RoleBinding render in the Helm release namespace, so the controller can only create jobs in another namespace if RBAC there is configured out of band; that is pre-existing and not changed here
  • serviceAccount.name: "" opts out entirely and falls back to the namespace default SA, preserving today's behaviour

Test plan

  • helm unittest charts/sourcegraph-executor/k8s
    • 14 passed
    • 7 new cases covering the default render, configureRbac: false, create: false with an existing name, empty name, a non-release executor.namespace, annotations, and automountToken: true
  • helm lint charts/sourcegraph-executor/k8s
    • Only the pre-existing empty-queueName warning
  • helm template sourcegraph-executor charts/sourcegraph-executor/k8s -n sourcegraph --set executor.queueName=codeintel renders the new ServiceAccount and the two ConfigMap keys
  • helm-docs regenerated charts/sourcegraph-executor/k8s/README.md

Follow-ups

  • Update the executor Kubernetes deployment docs once sourcegraph/sourcegraph#16392 lands and its release is known
  • Optionally extend examples/network-policy to key on the new ServiceAccount

Changelog

The sourcegraph-executor/k8s chart now creates a dedicated sg-executor-job ServiceAccount for executor job pods, with no RBAC bindings and no token mount, configurable under executor.kubernetesJob.serviceAccount

Job pods spawned by the Kubernetes executor ran as the namespace default
ServiceAccount with its token automounted, sharing an identity with every
other workload in the namespace. Add executor.kubernetesJob.serviceAccount
values, render an sg-executor-job ServiceAccount with no RBAC bindings and
automountServiceAccountToken: false, and pass the name and automount setting
to the executor via KUBERNETES_JOB_SERVICE_ACCOUNT_NAME and
KUBERNETES_JOB_AUTOMOUNT_SERVICE_ACCOUNT_TOKEN (sourcegraph/sourcegraph#16392).

The ServiceAccount is rendered only when executor.configureRbac is true, so
a second executor release in the same namespace does not try to own it.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0e96e-01bb-762e-a752-d2a3103593f0
Co-authored-by: Amp <amp@ampcode.com>
@github-actions

Copy link
Copy Markdown

A pod can only reference a ServiceAccount in its own namespace, so the job
ServiceAccount must live where the job pods run, not in the release
namespace.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0e96e-01bb-762e-a752-d2a3103593f0
Co-authored-by: Amp <amp@ampcode.com>
@marcleblanc2
marcleblanc2 marked this pull request as ready for review September 29, 2026 22:03
@marcleblanc2
marcleblanc2 requested a review from a team September 29, 2026 22:16
@michaellzc
michaellzc requested a review from a team September 29, 2026 22:45

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant