terraform_cloud, where it lasts until the run phase ends.
Dashboard Setup
Add an identity provider and a mapping, then monitor tokens and events.
SDK Usage
Configure the SDKs to do the exchange and the refresh for you.
Provider Guides
Step-by-step setup for each supported platform.
Terraform
Run the Terraform provider with no API key in your pipeline.
Why Use Workload Identity
An API key is a long-lived secret. You must store it in your CI system or your cloud, rotate it, and remove it when a person leaves. If the key leaks, an attacker can use it until you delete it. With workload identity federation:- No secret to store. The workload keeps only the identity provider id (
wip_...). This id is not a secret. - Short-lived credentials. Each Dodo token expires in 1 hour or less. A
terraform_cloudtoken lasts until the end of the run phase. To continue, the workload does a new exchange. - Precise trust. A mapping trusts only the JWTs that match its conditions, for example one repository and one branch.
- Same permissions model. The token gets the scopes of the mapping, and the usual API key rate limits apply.
- Audit. Each exchange, failure, revocation, and configuration change writes an event that you can see in the dashboard.
Supported Platforms
Key Concepts
Identity provider
Identity provider
An identity provider (
wip_...) tells Dodo Payments which issuer to trust. It has a provider type, an issuer URL, and an audience. Each provider belongs to one mode, test mode or live mode. A business can have 50 providers.Mapping
Mapping
A mapping (
wim_...) belongs to a provider. It has a list of claim conditions, a list of API scopes, an optional list of allowed CIDR ranges, and a token lifetime. A provider can have 50 mappings.Dodo token
Dodo token
The exchange gives a Dodo token that has the same format as an API key. Send it as
Authorization: Bearer <token>. There is no refresh token. To renew the token, do the exchange again.How the Exchange Works
- The workload requests an OIDC token from its platform. The audience of the token is the Dodo Payments audience of your mode.
- The workload sends the JWT and the identity provider id to
POST /workload-identity/token. This request does not need an API key. - Dodo Payments verifies the JWT signature with the public keys of the issuer. It also checks the issuer, the audience, the times, and the required claims.
- Dodo Payments finds the enabled mappings whose conditions all match the JWT. Exactly one mapping must match.
- Dodo Payments gives back a Dodo token with the scopes of that mapping.
Audience
The default audience is the Dodo Payments URL of the mode of the provider:
Thus a test mode JWT fails in live mode. A provider cannot use the audience of the other mode. The
kubernetes, gcp, vercel, and custom types must use the default audience. The github_actions, gitlab, terraform_cloud, and aws types can use a different audience.
Verification Rules
Token Lifetime
A Dodo token lives for thetoken_ttl_seconds of the mapping. The value is between 300 and 3600 seconds. The default is 3600 seconds (1 hour). The lifetime does not depend on the exp of the JWT.
The terraform_cloud type is different. HCP Terraform gives one JWT for each plan or apply phase, and that JWT can do one exchange only. Thus the Dodo token lives until the JWT expires, which is the end of the run phase, with a maximum of 24 hours.
A mapping can have a maximum of 500 active tokens. When it has 500, the exchange fails with the token_limit reason until tokens expire or you revoke them.
Scopes
The Dodo token gets the scopes of the mapping that matched. The workload cannot ask for more scopes. Each scope of a mapping must be a scope that the dashboard user who creates the mapping also holds. Refer to Dashboard Setup.IP Allowlist
A mapping can have a list of allowed CIDR ranges (allowed_cidrs), for IPv4 and IPv6.
- At the exchange. If the source IP is not in the list, the exchange fails with
invalid_grantand theip_not_allowedreason. - On each API call. The Dodo token gets a copy of the list. Each API call from an IP that is not in the list gets
403.
Replay Protection
Thegithub_actions, gitlab, terraform_cloud, and aws platforms give a new JWT for each request. For these types, the JWT must have a jti claim, and each JWT can do one exchange only. A second exchange with the same JWT fails with invalid_subject_token and the replay reason.
The kubernetes, gcp, vercel, and custom types do not enforce jti. For example, the kubelet writes the same service account token to a file for most of its life, and all processes in the pod read that token. For these types, these controls apply:
- The provider must use the Dodo Payments audience of its mode, thus no other service accepts the JWT.
- The mapping must pin a stable claim, for example
sub. - The Dodo token lives 1 hour or less.
- You can add
allowed_cidrsto the mapping.
Revocation
These actions stop Dodo tokens immediately:
Dodo Payments examines the JWT claims at the exchange only. A change on your platform after the exchange does not revoke a Dodo token. Examples are a moved repository, a deleted service account, or a renamed environment. The token stays valid until it expires, and the next exchange fails. For an immediate stop, use one of the actions in the table.
To revoke the current token from a workload, send it to the revoke endpoint. The response is
204:
Audit Events
The dashboard lists the events of your providers for 90 days.
Events record only an allowlist of claims, for example
iss, sub, jti, repository, ref, sha, and run_id. Dodo Payments never stores the JWT.
Reason Codes
Event Limits
Dodo Payments records failure events only for a known provider. A provider records a maximum of 60exchange_failed events each minute for one source IP, and 600 each minute for all source IPs. The first failure over a limit records one rate_limited event. These limits apply to the audit log only. They do not change the result of an exchange.
Exchange Errors
The exchange endpoint uses the OAuth 2.0 error format{ "error", "error_description" }.
error_description tells you which claim or value to correct. It does not show the expected value of a condition. The audit event has the full reason.
Dashboard Setup
Create your first provider and mapping.
SDK Usage
Use workload identity from the SDKs or with curl.