Vault JWT/OIDC "claim ... does not match" (bound_claims) in CI
The OIDC token verified, but a claim in it (the sub, repository, or ref) does not match what the role's bound_claims require. Vault enforces bound_claims exactly, so a branch or repo mismatch blocks login.
What this error means
A jwt login fails with "Code: 400 ... * error validating claims: claim \"sub\" does not match associated bound claim values" from a workflow on a branch or repo the role does not allow.
Error writing data to auth/jwt/login: Error making API request.
URL: PUT https://vault.example.com/v1/auth/jwt/login
Code: 400. Errors:
* error validating claims: claim "sub" does not match any associated bound claim valuesCommon causes
The subject or ref is not in bound_claims
GitHub's sub is like repo:my-org/my-repo:ref:refs/heads/main; a job on a different branch or a PR produces a sub the role does not permit.
bound_claims uses the wrong claim shape
Binding on sub with a literal that omits the ref: portion, or binding on a claim GitHub does not emit, never matches the real token.
How to fix it
Bind claims to the real token fields
- Decode a sample GitHub OIDC token to see
repository,ref, andsub. - Set
bound_claims(orbound_subject) to match the repo and branch you allow. - Re-run from an allowed ref.
vault write auth/jwt/role/github-actions \
role_type="jwt" user_claim="sub" \
bound_audiences="https://github.com/my-org" \
bound_claims='{"repository":"my-org/my-repo","ref":"refs/heads/main"}' \
token_policies="ci-read"Allow multiple refs with a glob
Use bound_claims_type=glob to permit several branches or tags.
vault write auth/jwt/role/github-actions \
bound_claims_type="glob" \
bound_claims='{"sub":"repo:my-org/my-repo:ref:refs/heads/*"}'How to prevent it
- Bind to
repositoryplusref/subthat reflect where CI actually runs. - Use
bound_claims_type=globwhen several branches must authenticate. - Inspect a real OIDC token before writing bound_claims, not the docs alone.