CircleCI now issues a third version of its OIDC (OpenID Connect) token, alongside the V1 and V2 tokens. In V3 the subject (sub) claim covers where the code was checked out from and where the pipeline config came from.
What’s new
- Jobs now get the V3 token in
$CIRCLE_OIDC_TOKEN_V3, alongside$CIRCLE_OIDC_TOKENand$CIRCLE_OIDC_TOKEN_V2. - The V3
subclaim has a new format, shown below.- It looks like
org:<org-id>:project:<project-id>:user:<user-id>:checkout-source:<checkout-source>:checkout-ref:<checkout-ref>:config-source:<config-source>:config-ref:<config-ref> - Segments are separated by
:instead of/. Branch names can contain/, so a/separator can be spoofed in wildcard matches. - Any
:inside a value is escaped as%3A.
- It looks like
- V3 adds four claims:
oidc.circleci.com/checkout-source,checkout-ref,config-sourceandconfig-ref. - V3 renames these claims:
vcs-origin→checkout-sourcevcs-ref→checkout-refpipeline-definition-id→pipeline-id- The old
pipeline-id→run-id
- The V2 token now also carries
checkout-source,checkout-ref,config-sourceandconfig-ref. Its existing claims andsubformat are unchanged. circleci run oidc getnow takes--v1,--v2or--v3to request a specific token version.- If that version can’t be minted, the command fails instead of returning a different version.
- With no flag it still returns a V2 token, falling back to V1.
- Example:
circleci run oidc get --v3 --aud "my-audience"
circleci run oidc getalso has a new--audflag to set a custom audience, for any token version.--claims '{"aud": "..."}'is deprecated but still works. You can’t pass both.
What to know
- Existing policies keep working, because V1 and V2 tokens are unchanged.
- If a job’s checkout values are missing, it gets no V3 token.
$CIRCLE_OIDC_TOKEN_V3won’t be set, andcircleci run oidc get --v3will fail. pipeline-idmeans something different in V3: it’s the pipeline definition, not the pipeline run. Update any policy that uses it before switching.
See Using OpenID Connect tokens in jobs for the full claims table and policy examples.