Secrets Manager: Workload identity federation (exchange external OIDC for SM JWT)

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Problem

GitLab Secrets Manager's non-CI/CD secret access (#594090, Phase 1) requires customers to store a long-lived GitLab credential in their workload environment. A CronJob refresher (for ESO) or a script (for ad-hoc use) authenticates as a service account or personal access token to call the SM access-token endpoint and mint a JWT.

That stored credential is the weakest link in the Phase 1 chain. If it leaks, the leaker can mint SM JWTs until the credential is rotated. We acknowledged this trade-off in #594090's Phase 1 design and noted federation as the cleaner long-term direction.

This issue captures the federation work as a follow-up to Phase 1.

Proposed Solution

A new Rails endpoint that accepts an external OIDC token issued by a configured trusted issuer, validates the signature, maps the external identity to a GitLab service account, and returns a Secrets Manager JWT.

The customer's workload no longer needs a stored long-lived GitLab credential. It uses an identity already issued by its host environment.

Example use cases

  • K8s pod on EKS with IAM Roles for Service Accounts (IRSA): the pod presents an AWS-signed OIDC token. GitLab is configured to trust the AWS JWKS. Pod gets an SM JWT.
  • K8s pod using its cluster Service Account token: the pod presents a token issued by the K8s API server's signer. GitLab is configured to trust that cluster's signer.
  • GCP workload: Cloud Run service or GKE pod presents a Google-signed identity token.
  • Azure workload: pod or service presents a Managed Identity token.

In each case, the workload never stores a GitLab credential. The token it presents is short-lived and rotated by the host environment.

Prior art

HashiCorp Vault has this pattern across several auth methods. Each is a useful reference for design and naming:

The pattern is the same: the auth method trusts an external signature and accepts identities the issuer vouches for. No stored long-lived credential on the client.

What GitLab would need to build

  • A new Rails auth endpoint that accepts an external OIDC token plus an indicator of which configured issuer to validate against.
  • JWT signature verification against the issuer's JWKS.
  • Configuration surface (UI / API) for instance or group admins to register trusted issuers and map external identity claims to GitLab service accounts.
  • Mapping rules from external identity claims (sub, aud, additional issuer-specific claims) to GitLab service accounts.
  • Documentation per supported environment (EKS, GKE, AKS, on-prem K8s, generic OIDC).

Why this matters

  • No long-lived GitLab credentials in customer clusters. Removes the biggest weak spot of Phase 1.
  • Cleaner audit. The cloud provider's identity becomes the source of truth.
  • Standard pattern customers already understand. Same mental model as HashiCorp Vault's auth methods.
  • Cross-system identity hygiene. Customers can rotate cloud identities once and have it reflected everywhere.

Scope

  • In scope (this issue): design and implementation of the federation endpoint, the JWKS verification layer, and the issuer-to-service-account mapping surface.
  • Out of scope: Phase 1 of SM API access (#594090). That ships first with PAT, SA, PrAT, and GrAT auth. This issue is the second step on top of it.
  • #594090 (Phase 1 SM API access, this issue's foundation)
  • &20382 (K8s Operator)
  • &21177 (Terraform Provider)

cc @fcatteau @mmishaev @jrandazzo

Edited by 🤖 GitLab Bot 🤖