Safeguard
Security Guides•

How do you lock down Vault JWT auth for CI jobs with bound claims?

Vault's JWT auth method checks audience, subject, and custom claims before login. See how bound_audiences, bound_subject, and bound_claims limit CI jobs.

Safeguard Security Team
4 min read

Vault's JWT auth method lets a CI job log in with the token its platform issues, and a role decides who gets in. Lock the role down with bound_audiences, bound_subject, and bound_claims so only the intended project and ref match. A role with no bound claims accepts any valid token from the issuer.

Definition

The JWT auth method lets clients authenticate to Vault using OIDC or by presenting a JWT directly. For a JWT login, Vault cryptographically verifies the token using locally provided keys, or keys fetched from an OIDC discovery service if you configure one. Only one signature verification method is allowed per mounted backend.

A role then states what to accept. Roles are named, set the type (OIDC or JWT), attach policies, and carry the claim rules.

The three controls

SettingWhat it enforces
bound_audiencesThe role's value must exactly match at least one aud claim in the JWT. Vault documents this as strict from version 1.17
bound_subjectMust match the sub claim of the token
bound_claimsArbitrary claims must match. A list matches if the claim equals any item in it

The documentation example for bound_claims says only JWTs containing both the named claims with matching values are authorized. That is the pattern you want for CI: require the claims that identify your repository and context, and nothing else gets in.

The user_claim setting points at data in the JWT to name the identity alias, so audit logs show something meaningful. Pick a claim that identifies the project or workflow rather than a free text field.

Why CI roles go wrong

The common failure is a role that checks only the issuer. Every job on that CI platform, including jobs from unrelated projects on a shared instance, then produces a token Vault accepts. GitLab's own Vault guide says roles should always be limited to a project or namespace, since otherwise any JWT from the GitLab instance might authenticate. GitHub's guidance has the same theme: you must define at least one condition.

Steps to build a tight role

  1. Pick the claims your CI platform issues that identify the project. For GitLab, stable ones include project_id and namespace_id; for GitHub, repository and environment claims.
  2. Set bound_audiences to a value unique to Vault, and configure the job to request that audience.
  3. Add bound_claims for the project identifier and for the protected ref or environment.
  4. Attach a policy that reads only the paths this job needs. One role per job family, not one role for every pipeline.
  5. Set a short token TTL on the role so the Vault token expires soon after the job. Check the exact parameter names in the Vault reference for your version.
  6. Choose a clear user_claim so audit entries are traceable to a project.
  7. Test refusals: a token from another project, a feature branch, and a wrong audience should all fail.

Verification keys

Decide how Vault validates signatures. With OIDC discovery, validation criteria such as issuer and audience are applied. With a JWKS URL or static keys, you manage which keys are trusted. Plan for key rotation on the CI platform side; if the platform rotates keys and your configuration pins an old one, logins fail until you update it.

Quick check

Is bound_subject enough by itself?

It helps, but combine it with bound_audiences and the claims that identify the project and ref, so a renamed or recreated project does not inherit trust.

Does Vault care about the CI platform at all?

Only through the claims and keys you configure. That is why the role must be specific.

Safeguard policies and gates can review pull requests that touch pipeline configuration, and compliance and evidence automation can keep records of access reviews. A free scan is at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.