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

# External JWT

> Configure Okta, Entra, Auth0, or custom OIDC JWTs as Bearer tokens for TrueFoundry APIs and the AI Gateway.

External JWT Identity Providers let TrueFoundry validate JWT tokens issued by your organization's IdP — Okta, Azure AD / Entra, Auth0, or another OIDC-compatible provider. The caller sends the IdP JWT as a Bearer token on every TrueFoundry API or gateway call. After validation, TrueFoundry resolves the token to a user or virtual account and uses that identity for RBAC.

For pods, CI, and cloud roles that use Kubernetes, GitHub, AWS, or GCP identity, see [Workload Identity Federation](https://www.truefoundry.com/docs/platform/identity-providers/workload-identity-federation/overview.md) instead. That path exchanges a platform JWT for a short-lived TrueFoundry token and does not use Resolve Token To. For a side-by-side comparison, see the [Identity Providers overview](https://www.truefoundry.com/docs/platform/identity-providers/overview.md).

## When to use External JWT

Use External JWT when an external application, service, gateway client, or end user already has a JWT from your IdP, and needs to access TrueFoundry APIs, AI Gateway, MCP Gateway, models, or MCP servers without first generating a TrueFoundry token.

Common use cases include:

1. Service-to-service authentication where an application presents an IdP-issued JWT.
2. B2B or partner access where users authenticate with their own organization's IdP.
3. Per-user gateway access where TrueFoundry should preserve the upstream user's identity from the JWT.

## How token resolution works

1. The user or application authenticates with your IdP and receives a JWT.
2. The caller sends the JWT to TrueFoundry as a Bearer token.
3. TrueFoundry validates the token signature using the configured JWKS URI.
4. TrueFoundry validates the issuer and allowed audience values, if configured.
5. TrueFoundry resolves the token to either a virtual account or a TrueFoundry user.
6. RBAC is evaluated using the resolved TrueFoundry identity.

> [!NOTE]
>
> TrueFoundry never handles the user's IdP credentials. Your IdP remains the source of truth for authentication.

## What External JWT can and can't do

External JWT validates IdP-issued tokens and resolves them to TrueFoundry identities for API and AI Gateway access. It is not a replacement for SSO or user provisioning.

| Capability | Supported? | Behavior |
| - | - | - |
| Validate JWT signatures using JWKS | Yes | TrueFoundry fetches public keys from the configured JWKS URI and verifies incoming JWT signatures. |
| Validate issuer and audience | Yes | Tokens are rejected if `iss` does not match, or if no JWT `aud` value intersects **Allowed Audiences**. |
| Resolve a token to a virtual account | Yes | The configured name claim must match an identity provider mapping on an existing virtual account. |
| Resolve a token to a TrueFoundry user | Yes | The configured email claim must match an existing user in the tenant. |
| Map a resolved user to a team | Yes | The configured team claim must match an identity provider mapping on an existing team. |
| Create a missing TrueFoundry user | No | If the email claim does not match an existing user, the token is not resolved to a user. Use [Manage Users](https://www.truefoundry.com/docs/platform/user-management.md#user-provisioning) to create users through SCIM, JIT, or invites. |
| Create a missing team | No | If the team claim does not match an existing team mapping, TrueFoundry does not create the team. Create the team first and configure its identity provider mapping. |
| Log users into the TrueFoundry UI | No | Use [SSO](https://www.truefoundry.com/docs/sso.md) for interactive user login. |
| Sync or deactivate users from your IdP | No | Use SCIM provisioning for user lifecycle sync and deprovisioning. |

## Configure an Identity Provider

Go to **Settings > Security & Access > Identity Providers**, and click **+** (Add Identity Provider).

![Identity Providers section in TrueFoundry Security and Access settings](https://mintcdn.com/truefoundry/xnxwG9wbAPzCd_DD/images/docs/platform/security-access-identity-providers.png?fit=max\&auto=format\&n=xnxwG9wbAPzCd_DD\&q=85\&s=0e862ee64317b5cce9307757f408dd16)

Identity Providers section in Security & Access settings

![Add Identity Provider drawer showing JWT validation and resolve-to settings](https://mintcdn.com/truefoundry/xnxwG9wbAPzCd_DD/images/docs/platform/add-identity-provider-drawer.png?fit=max\&auto=format\&n=xnxwG9wbAPzCd_DD\&q=85\&s=91e0e2fa917aaedd33e0ddf1f332a5f7)

Add Identity Provider form

### Identity Provider fields

**Enabled** `boolean` *required*

Enable or disable this Identity Provider. Other settings on the form only take effect when this is enabled.

**Provider Name** `string` *required*

A unique identifier for this Identity Provider configuration. Use lowercase letters, numbers, and hyphens only. The name must be 3-32 characters, start with a lowercase letter, and end with a lowercase letter or number.

Example: `my-okta-provider`

**Issuer URL** `string` *required*

The OIDC issuer URL. This must exactly match the `iss` claim in JWT tokens issued by your provider.

Example: `https://accounts.example.com`

**Allowed Audiences** `string[]` *required*

One or more allowed audience values. The JWT is accepted when **any** of its `aud` values (string or array) intersects this list. A token whose audiences do not overlap the list is rejected.

**JWKS URI** `string` *required*

The public HTTPS endpoint exposing your provider's JSON Web Key Set (JWKS). TrueFoundry fetches public keys from this endpoint to verify JWT signatures. Make sure the endpoint is reachable from the TrueFoundry control plane.

Example: `https://accounts.example.com/.well-known/jwks.json`

## Resolve tokens to TrueFoundry identities

The **Resolve Token To** section controls how validated JWTs are mapped to TrueFoundry identities.

> [!NOTE]
>
> If both virtual account and user resolution are configured, virtual account resolution takes precedence.

### Resolve to a virtual account

Use this when the JWT represents a machine user, application, shared external identity, or service-to-service caller.

**Name Claim** `string` *required*

The JWT claim whose value identifies the virtual account mapping.

Common examples: `sub`, `client_id`

**User Slug Claim** `string`

Optional claim used to distinguish individual external users within a shared virtual account. Configure this when one virtual account represents multiple external users and you want each token to resolve to a distinct user slug.

After configuring the provider, add the provider mapping on the virtual account. See [Identity provider mappings for virtual accounts](https://www.truefoundry.com/docs/platform/virtual-account-management.md#identity-provider-mappings).

### Resolve to a TrueFoundry user

Use this when the JWT represents a human user who should map to an existing TrueFoundry user account.

**Email Claim** `string` *required*

The JWT claim containing the user's email address. TrueFoundry uses this value to match an existing TrueFoundry user.

Common example: `email`

**Team Claim** `string`

Optional. The JWT claim containing the user's team or group value. TrueFoundry uses this value with team-level identity provider mappings to assign the resolved user to the matching team.

Common examples: `groups`, `team`

After configuring the provider, add the provider mapping on each target team. See [Identity provider mappings for teams](https://www.truefoundry.com/docs/platform/team-management.md#identity-provider-mappings).

## Advanced claim overrides

**Email Claim Override** `string`

The JWT claim to use for email mapping. Defaults to `email` if not set.

**Unique ID Claim Override** `string`

The JWT claim to use as the unique identifier for the subject. Defaults to `sub` if not set.

## Examples

> [!NOTE]
>
> `config.type: jwt` is a forthcoming schema field. Keep it in these examples for the upcoming shape; omit it on apply until your control plane accepts that field.

> [tab] Okta
>
> ```yaml theme={"dark"}
> name: my-okta-provider
> config:
>   type: jwt
>   issuer: https://example.okta.com
>   audiences:
>     - api://truefoundry
>   jwks_uri: https://example.okta.com/oauth2/v1/keys
> resolve_token_to:
>   virtual_account:
>     name_claim: client_id
> ```

> [tab] Azure AD
>
> ```yaml theme={"dark"}
> name: my-azure-provider
> config:
>   type: jwt
>   issuer: https://login.microsoftonline.com/<tenant-id>/v2.0
>   audiences:
>     - <client-id>
>   jwks_uri: https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys
> resolve_token_to:
>   user:
>     email_claim: email
>     team_claim: groups
> ```

## Call the AI Gateway with an IdP token

Users can call the AI Gateway with the JWT issued by your IdP, without a TrueFoundry login or a Personal Access Token. Usage is attributed to each user.

1. **Add the Identity Provider.** Configure the JWKS URI, issuer, and allowed audiences as described above, and resolve tokens to a TrueFoundry user (and team, if you want access granted at team level).
2. **Grant access to the model account.** Access is controlled per model account, so give the user or team the **Model Account User** role on the account that holds the models. To expose only some models, put them in their own model account. See [Gateway Access Control](https://www.truefoundry.com/docs/ai-gateway/gateway-access-control.md).
3. **Send the IdP JWT as the Bearer token.**

```bash theme={"dark"}
curl {GATEWAY_BASE_URL}/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <IdP JWT>" \
  -d '{
    "model": "<model-account>/<model-name>",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
```

Replace `{GATEWAY_BASE_URL}` with the base URL of your AI Gateway.

The request is attributed to the TrueFoundry user whose email matches the token's email claim, and appears under that user in traces and request logs. The user must already exist in TrueFoundry, created through SCIM, JIT provisioning, or an invite. If no user matches the email, the gateway returns `401 Invalid token` and does not create a user.

## Troubleshooting

> [accordion] Token authentication fails
>
> Verify that the JWKS URI is correct and reachable from the TrueFoundry control plane. Also check that the token's `iss` claim matches the configured issuer and that the token's `aud` claim matches one of the allowed audiences.

> [accordion] Token validates but does not map to a virtual account
>
> Check that the provider is configured to resolve to a virtual account, then verify that the JWT claim configured as the name claim matches the claim value configured on the target virtual account.

> [accordion] Token validates but does not map to the expected team
>
> Check that the provider is configured to resolve to a TrueFoundry user, then verify that the JWT team claim matches the claim value configured on the target team.

> [accordion] Changing the email claim has no effect on existing users
>
> This applies when a custom Identity Provider is configured for non-browser access (for example scripts or service tokens) and shares the same JWKS as the identity provider used for SSO login.
>
> When both providers share the same JWKS, TrueFoundry resolves tokens using the login provider's identifier claim logic, which defaults to `email`. The **Email Claim** setting on the custom Identity Provider is ignored, so tokens still authenticate but resolve to the user matched by the old claim.
>
> To change the claim used for resolution (for example to `upn`), set all four environment variables in the `values.yaml` of the `truefoundry` Helm installation:
>
> ```yaml lines theme={"dark"}
> servicefoundryServer:
>   env:
>     EXTERNAL_OAUTH_USER_INFO_EMAIL_KEY_NAME: "upn"
>     EXTERNAL_OAUTH_TOKEN_EMAIL_CLAIM_KEY_NAME: "upn"
>     EXTERNAL_OAUTH_TOKEN_ID_CLAIM_KEY_NAME: "upn"
> tfy-llm-gateway:
>   env:
>     EXTERNAL_OAUTH_EMAIL_CLAIM_KEY: "upn"
> ```
>
> All four variables must be set. `EXTERNAL_OAUTH_EMAIL_CLAIM_KEY` is easy to miss because it lives on the `tfy-llm-gateway` component rather than `servicefoundryServer`. See [External SSO (OIDC/SAML)](https://www.truefoundry.com/docs/deploy-control-plane-with-external-oauth.md) for the full list of claim override variables.
>
> To verify the change, test with a user whose `email` claim and target claim point to different accounts. Confirm the resolved subject in the AI Gateway logs matches the new claim, not `email`.
>
> > [!NOTE]
> >
> > If the `aud` claim is identical between your SSO login tokens and your out-of-browser tokens, a separate custom Identity Provider may not be needed at all. Audience validation for the login identity provider is planned for an upcoming release, so confirm `aud` consistency now.

> [accordion] A user token resolves as a virtual account
>
> If both user and virtual account resolution are configured, virtual account resolution takes precedence. Disable virtual account resolution if the same tokens should resolve directly to TrueFoundry users.


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