> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workload Identity for a Custom OIDC Issuer

> Trust JWTs from any OIDC issuer with an HTTPS URL, through a discovery document or uploaded public keys, and exchange them for Dodo tokens.

Use a `custom` provider for an issuer that has no built-in type, for example a self-hosted identity provider or a CI system with OIDC support.

## Provider Settings

| Setting | Value |
| - | - |
| Provider type | `custom` |
| Issuer | Any HTTPS URL. The `iss` claim must be equal to this value. |
| Audience | Must be `https://live.dodopayments.com` or `https://test.dodopayments.com` |
| Keys | The default discovery endpoint of the issuer, a `discovery_url`, or uploaded keys (JWKS) |
| Replay protection | Not enforced. The audience and the `sub` pin replace it. |
| JWT lifetime | 1 hour or less. |

A `custom` provider cannot use the issuer host of a built-in type, for example `token.actions.githubusercontent.com` or `gitlab.com`. Use the built-in type for these issuers.

### Keys

Select one key source:

* **Discovery (default).** Dodo Payments reads the discovery document of the issuer and its `jwks_uri`. The `issuer` in the discovery document must be equal to the issuer of the provider.
* **Discovery URL.** Enter a `discovery_url` when the discovery document is not at the default location.
* **Uploaded keys.** For an issuer with no public JWKS, upload a JWKS. It must have 1 to 20 public keys, with a size of 64 KB or less. Each key must have a `kty` of `RSA`, `EC` (`P-256` or `P-384`), or `OKP` (`Ed25519`). Private key members are not permitted.

Dodo Payments gets the remote keys over HTTPS only. It does not follow redirects, and it refuses private IP addresses. The JWKS must have a minimum of one key with a `kid` and a permitted algorithm.

## Required Claims

The mapping must pin `sub` with an exact value:

```json theme={null}
[
  { "claim": "sub", "value": "service:billing-worker" }
]
```

The JWT must have `kid` in its header, and `iss`, `aud`, `sub`, `iat`, and `exp` in its payload. Refer to [Verification Rules](https://docs.dodopayments.com/developer-resources/workload-identity/overview.md#verification-rules).

## SDK Usage

Write the JWT to a file, and point `DODO_PAYMENTS_IDENTITY_TOKEN_FILE` to it. The `file()` helper reads the file for each exchange.

```typescript TypeScript theme={null}
import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  environment: 'live_mode',
  workloadIdentity: {
    identityProviderId: process.env.DODO_PAYMENTS_IDENTITY_PROVIDER_ID,
    provider: DodoPayments.workloadIdentity.file(),
  },
});
```

```python Python theme={null}
import os
from dodopayments import DodoPayments
from dodopayments.workload_identity import WorkloadIdentity, file

client = DodoPayments(
    environment="live_mode",
    workload_identity=WorkloadIdentity(
        identity_provider_id=os.environ["DODO_PAYMENTS_IDENTITY_PROVIDER_ID"],
        provider=file(),
    ),
)
```

```go Go theme={null}
client := dodopayments.NewClient(
	option.WithEnvironmentLiveMode(),
	option.WithWorkloadIdentity(option.WorkloadIdentity{
		IdentityProviderID: os.Getenv("DODO_PAYMENTS_IDENTITY_PROVIDER_ID"),
		Provider:           workloadidentity.File(""),
	}),
)
```

You can also send the JWT to the exchange endpoint yourself. Refer to [Raw HTTP Exchange](https://docs.dodopayments.com/developer-resources/workload-identity/sdk-usage.md#raw-http-exchange).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.