Skip to content
Latchkey

Vault Kubernetes auth "service account not authorized" in CI

The Kubernetes JWT was accepted, but the service account or namespace it belongs to is not bound to the Vault role. Vault checks bound_service_account_names and bound_service_account_namespaces and rejects anything outside them.

What this error means

A vault write auth/kubernetes/login fails with "Code: 403 ... * service account name not authorized" from a CI pod or runner.

vault
Error writing data to auth/kubernetes/login: Error making API request.

URL: PUT https://vault.example.com/v1/auth/kubernetes/login
Code: 403. Errors:

* service account name not authorized

Common causes

The service account is not bound to the role

The pod runs as a service account not listed in bound_service_account_names, so Vault denies it.

The namespace is not permitted

The role's bound_service_account_namespaces does not include the CI namespace the pod runs in.

How to fix it

Bind the CI service account and namespace

  1. Identify the service account and namespace of the CI pod.
  2. Add both to the Kubernetes auth role bindings.
  3. Re-run the login from that pod.
Terminal
vault write auth/kubernetes/role/ci \
  bound_service_account_names=ci-runner \
  bound_service_account_namespaces=ci \
  token_policies=ci-read token_ttl=15m

Send the pod token to Vault

Log in with the mounted service account token as the role JWT.

bash
JWT=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
vault write auth/kubernetes/login role=ci jwt="$JWT"

How to prevent it

  • Keep role bindings in sync with the service accounts CI actually uses.
  • Scope one role per namespace/service account rather than a broad binding.
  • Verify the token reviewer permissions Vault needs are in place.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →