> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-docs-2516.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Use federated identities with SDK

> Use identity federation with JSON Web Tokens (JWTs) to authenticate with the W&B SDK and CLI without API keys.

Use identity federation to sign in to the W\&B SDK and CLI with your organizational credentials, instead of using a long-lived API key. If your W\&B organization admin has configured SSO for your organization, you already use those credentials to sign in to the W\&B App UI. Identity federation is like SSO for the W\&B SDK, but uses JSON Web Tokens (JWTs) directly. Use identity federation as an alternative to API keys.

This page is for organization admins who configure the JWT issuer for a W\&B organization. It's also for users or service accounts that authenticate to W\&B using JWTs.

[RFC 7523](https://datatracker.ietf.org/doc/html/rfc7523) is the basis for identity federation with SDK.

<Note>
  Identity federation is available in preview for Multi-tenant Cloud, Dedicated Cloud, and Self-Managed. It requires an [Enterprise license](/platform/hosting/enterprise-licenses). For details or assistance, contact your AISE or [support](mailto:support@wandb.com).

  Identity federation covers W\&B Models. W\&B Weave and Serverless Inference don't support it yet. Use an API key for those products.
</Note>

<Note>
  This page uses the terms "identity provider" and "JWT issuer" interchangeably. Both refer to the same thing in the context of this capability.
</Note>

## Set up a JWT issuer

Before users can authenticate with JWTs, an organization admin must federate the W\&B organization with a publicly accessible JWT issuer.

1. In your organization dashboard, go to the **Settings** tab.
2. Open the **Authentication** tab and find **JWT Issuers**.
3. Click **Add JWT Issuer**.
4. Enter the JWT issuer URL and click **Create**.

W\&B automatically looks for an OIDC discovery document at the path `${ISSUER_URL}/.well-known/openid-configuration`. From the discovery document, W\&B locates the JSON Web Key Set (JWKS) at the URL that the document specifies. W\&B uses the JWKS to validate JWTs in real time and confirm that the identity provider issued them.

After this step, your W\&B organization is federated with the JWT issuer. Users in your organization can then authenticate to W\&B using JWTs issued by that provider.

Repeat these steps to federate with more than one issuer. An organization can trust multiple JWT issuers at the same time, which is useful when different teams authenticate through different identity providers. W\&B selects which issuer to validate a token against using the token's `iss` claim, so every issuer URL must be distinct.

To stop trusting an issuer, click the delete icon next to it in the **JWT Issuers** list. Deleting an issuer also deletes every external service account created against it.

## Use the JWT to access W\&B

After an organization admin sets up a JWT issuer, users can start accessing W\&B projects using JWTs issued by that identity provider. To use a JWT to access W\&B, follow these steps:

1. Sign in to the identity provider using one of the mechanisms available in your organization. You can access some providers with an API or SDK, while others are only accessible through a UI. Contact your W\&B organization admin or the owner of the JWT issuer for details.
2. After you've retrieved the JWT by signing in to your identity provider, store it in a file at a secure location. Configure the absolute file path in an environment variable `WANDB_IDENTITY_TOKEN_FILE`.
3. Access your W\&B project using the W\&B SDK or CLI. The SDK or CLI automatically detects the JWT and exchanges it for a W\&B access token after validating the JWT. The W\&B access token grants access to the APIs that your AI workflows use, such as logging runs, metrics, and artifacts. By default, the access token is stored at the path `~/.config/wandb/credentials.json`. You can change that path by specifying the environment variable `WANDB_CREDENTIALS_FILE`.

<Note>
  JWTs are short-lived credentials that address the shortcomings of long-lived credentials such as API keys and passwords. The JWT expiry time depends on your identity provider's configuration. Refresh the JWT before it expires, and ensure that it's stored in the file referenced by the environment variable `WANDB_IDENTITY_TOKEN_FILE`.

  The W\&B access token expires after 14 days, after which the SDK or CLI uses your JWT to refresh it. If the user JWT has also expired by that time and isn't refreshed, authentication fails. If possible, implement the JWT retrieval and post-expiry refresh mechanism as part of the AI workload that uses the W\&B SDK or CLI.
</Note>

### JWT validation

To ensure that only valid tokens grant access, W\&B validates the JWT when the SDK or CLI exchanges it for a W\&B access token. A failed check returns an `invalid_grant` error whose `error_description` field names the specific check that failed.

| Claim             | Requirement                                                                                                                                                                                                                 |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Signature         | W\&B verifies the signature using the JWKS for the issuer named in `iss`. W\&B checks the signature before it checks any other claim. A failure here means there's a problem with your JWKS or with how your JWT is signed. |
| `iss`             | Must exactly match one of the issuer URLs configured for the organization.                                                                                                                                                  |
| `sub`             | Required. For an external service account, must exactly match the **Subject** that a team admin configured. For a human user, see [How W\&B identifies a human user](#how-wb-identifies-a-human-user).                      |
| `aud`             | Required. See [Audience requirements](#audience-requirements).                                                                                                                                                              |
| `exp`             | Required. W\&B rejects an expired token.                                                                                                                                                                                    |
| `iat`             | Required.                                                                                                                                                                                                                   |
| `exp` minus `iat` | Must be 24 hours or less. W\&B rejects a JWT whose lifetime is longer, even if it hasn't expired yet.                                                                                                                       |
| `nbf`             | Optional. If present, the time it names must already have passed.                                                                                                                                                           |
| `jti`             | Optional. If present, W\&B records the value and rejects any later JWT that reuses it. See [A JWT is rejected as a replay](#a-jwt-is-rejected-as-a-replay).                                                                 |

#### How W\&B identifies a human user

W\&B matches a human user's JWT to a W\&B user by email address, checking the following claims in order and stopping at the first one that matches a user:

1. The `sub` claim, when its value is the user's email address.
2. The `email` claim.
3. Any other claim whose name contains `email`, such as `work_email`.

This means your identity provider can keep an opaque `sub`, such as a UUID, as long as the token also carries the user's email address in a claim. Earlier releases required `sub` itself to be the email address. The fallbacks require W\&B Server v0.74.0 or later, and are already available on Multi-tenant Cloud.

The matched user must already be a member of the W\&B organization. Identity federation authenticates existing users. It doesn't create them. Provision users through SSO or [SCIM](/platform/hosting/iam/scim) first.

#### Audience requirements

The value that W\&B requires in the `aud` claim depends on your deployment type.

| Deployment                                                                                                                              | Required `aud` value                                                                                                                                                                   |
| --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Multi-tenant Cloud](/platform/hosting/hosting-options/multi_tenant_cloud)                                                              | Exactly one value: the name of the W\&B organization that houses the project you're accessing. The value isn't configurable.                                                           |
| [Dedicated Cloud](/platform/hosting/hosting-options/dedicated-cloud) and [Self-Managed](/platform/hosting/hosting-options/self-managed) | Any value in the environment variable `FEDERATED_AUTH_AUDIENCES`, a comma-separated list of allowed audiences. When you don't set the variable, W\&B accepts the single value `wandb`. |

On Dedicated Cloud or Self-Managed, you can turn audience validation off entirely by setting the environment variable `SKIP_AUDIENCE_VALIDATION` to `true`. For both variables, see [Advanced environment variables](/platform/hosting/iam/advanced_env_vars).

<Warning>
  Setting `SKIP_AUDIENCE_VALIDATION` to `true` turns off a check that RFC 7523 requires. Without it, W\&B accepts a JWT that your identity provider minted for a different service. Prefer adding your audience value to `FEDERATED_AUTH_AUDIENCES`.
</Warning>

## External service accounts

With identity federation for the SDK and CLI, you can add external service accounts that use JWTs for authentication. These are in addition to the built-in service accounts, which use long-lived API keys. The organization's configured issuer must issue those JWTs. A team admin can configure external service accounts within the scope of a team, like the built-in service accounts.

To configure an external service account, complete the following steps:

1. Go to the **Service Accounts** tab, either for your team or in your organization's account settings.
2. Click **New service account**.
3. Provide a name for the service account.
4. If you're creating the service account from your organization's account settings, select a **Default Team**. See [Organization-scoped service accounts](/platform/hosting/iam/service-accounts#organization-scoped-service-accounts).
5. Select **Federated identity** as the **Authentication Method**.
6. Select the **JWT Issuer** that issues this service account's tokens.
7. Provide a **Subject**. See [Determine the Subject value for your identity provider](#determine-the-subject-value-for-your-identity-provider).
8. Click **Create service account**.

After this step, the external service account is registered with the team and can use JWTs issued by the configured identity provider to access W\&B. The `sub` claim in the external service account's JWT must equal the subject configured by the team admin. W\&B verifies that claim as part of [JWT validation](#jwt-validation). The `aud` claim requirement is the same as for human user JWTs.

Note the following constraints:

* **Federated identity** is unavailable until an organization admin adds at least one JWT issuer. Until then, the option can't be selected and reads "Add a JWT Issuer in Authentication Settings to use this method."
* You choose the authentication method when you create the service account. The **JWT Issuer** and **Subject** are fixed at that point, and you can't change them later.
* Choosing **Federated identity** doesn't permanently exclude API keys. To issue one for an existing service account, open its row menu in the **Service Accounts** table and click **Create API key**.

When [using an external service account's JWT to access W\&B](#use-the-jwt-to-access-wb), it's often more practical to automate the workflow. Automation generates the initial JWT and refreshes it as needed. To attribute runs logged using an external service account to a human user, configure the environment variables `WANDB_USERNAME` or `WANDB_USER_EMAIL` for your AI workflow, similar to built-in service accounts.

<Note>
  W\&B recommends using a mix of built-in and external service accounts across your AI workloads with different levels of data sensitivity. This mix balances flexibility and simplicity.
</Note>

### Determine the Subject value for your identity provider

The value you enter for **Subject** must exactly match the `sub` (subject) claim in JWTs issued by your identity provider for the service account. W\&B applies the same comparison for every identity provider. The match is exact, case-sensitive, and whitespace-sensitive, so even a trailing space or a difference in capitalization causes authentication to fail.

The W\&B App accepts any non-empty **Subject** without validating its value, because the value depends on the identity provider. W\&B can't detect an incorrect value when you create the service account. Instead, authentication fails later, when the service account presents its JWT.

The most reliable way to determine the correct value is to read it from a real token. Obtain a sample JWT issued for the service account, base64url-decode its payload (the middle segment, between the two dots) locally, and copy the `sub` value verbatim into the **Subject** field. Don't paste JWTs into third-party online decoders, because a JWT is a credential.

The value differs by provider. The following are typical, but always confirm them against an actual token:

| Identity provider  | Where to find the `sub` value                                                                                                                                                                                                                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Microsoft Entra ID | The service principal's **Object ID**, found under **Enterprise Applications** in the [Microsoft Entra admin center](https://entra.microsoft.com). Use the **Enterprise Application** (service principal) Object ID, not the **App registration** Object ID. For app-only (client credentials) tokens, this is typically the value Entra ID places in `sub`. |
| Google Cloud (GCP) | The `sub` value from the ID token that Google issues for the service account.                                                                                                                                                                                                                                                                                |
| Kubernetes         | The projected service account token uses the form `system:serviceaccount:<namespace>:<service-account-name>`.                                                                                                                                                                                                                                                |

## Examples

The following examples show a complete token payload and the matching workload configuration. Both assume a W\&B organization named `acme-corp` on Multi-tenant Cloud, federated with the issuer `https://idp.example.com`.

### Authenticate as a user

Use this pattern for interactive work, such as a notebook or a developer laptop, where a human signs in to the identity provider.

Decode a token your identity provider issued for you and confirm the payload carries the claims W\&B needs:

```json title="Decoded JWT payload" theme={null}
{
  "iss": "https://idp.example.com",
  "sub": "alex@example.com",
  "aud": "acme-corp",
  "iat": 1756400000,
  "exp": 1756403600
}
```

If your identity provider issues an opaque `sub`, add the user's email address in a separate claim instead:

```json title="Decoded JWT payload, opaque subject" theme={null}
{
  "iss": "https://idp.example.com",
  "sub": "8f14e45f-ceea-467a-9c8a-3ba1e9ba4a1c",
  "email": "alex@example.com",
  "aud": "acme-corp",
  "iat": 1756400000,
  "exp": 1756403600
}
```

Write the token to a file, point `WANDB_IDENTITY_TOKEN_FILE` at it, and sign in:

```bash theme={null}
# Retrieve a token from your identity provider and store it securely.
umask 077
your-idp-cli get-token > "$HOME/.config/wandb/identity-token"

export WANDB_IDENTITY_TOKEN_FILE="$HOME/.config/wandb/identity-token"
export WANDB_CREDENTIALS_FILE="$HOME/.config/wandb/credentials.json"

wandb login
```

Logging a run requires no further changes. The SDK reads the same environment variables:

```python theme={null}
import wandb

run = wandb.init(entity="acme-corp-team", project="fraud-detection")
run.log({"accuracy": 0.91})
run.finish()
```

### Authenticate as an external service account

Use this pattern for unattended workloads, such as a training job on Kubernetes, where the platform mints and rotates the token for you.

First, a team admin creates the external service account, following [External service accounts](#external-service-accounts). For a Kubernetes workload, the **Subject** is the projected service account token's `sub`:

```text theme={null}
system:serviceaccount:ml-training:trainer
```

The projected token that Kubernetes mounts into the Pod carries a matching payload:

```json title="Decoded JWT payload" theme={null}
{
  "iss": "https://idp.example.com",
  "sub": "system:serviceaccount:ml-training:trainer",
  "aud": "acme-corp",
  "iat": 1756400000,
  "exp": 1756403600
}
```

Set the `audience` on the projected volume so that Kubernetes mints the token with the `aud` value W\&B expects, and pin `WANDB_CREDENTIALS_FILE` to a writable path:

```yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  name: trainer
  namespace: ml-training
spec:
  serviceAccountName: trainer
  containers:
    - name: train
      image: your-registry/trainer:latest
      env:
        - name: WANDB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/wandb/token
        - name: WANDB_CREDENTIALS_FILE
          value: /tmp/wandb-credentials.json
        # Attribute the runs this service account logs to a human user.
        - name: WANDB_USER_EMAIL
          value: alex@example.com
      volumeMounts:
        - name: wandb-identity-token
          mountPath: /var/run/secrets/wandb
          readOnly: true
  volumes:
    - name: wandb-identity-token
      projected:
        sources:
          - serviceAccountToken:
              path: token
              audience: acme-corp
              expirationSeconds: 3600
```

Kubernetes refreshes the projected token in place before it expires, so the workload doesn't need its own refresh logic.

## Troubleshoot identity federation

The following sections describe common identity federation authentication failures and how to resolve them.

### A JWT is rejected as a replay

Authentication fails with a `jti_known` error. Your identity provider includes a `jti` claim, and W\&B has already accepted that token. W\&B records each `jti` it accepts and rejects reuse, which prevents a captured JWT from being replayed.

This most often happens when `wandb.login()` and `wandb.init()` resolve `WANDB_CREDENTIALS_FILE` to different paths. The first call exchanges the JWT and caches the W\&B access token. The second call doesn't find that cache, presents the same JWT again, and W\&B rejects it as a replay.

Set `WANDB_CREDENTIALS_FILE` to a single absolute path that every code path in the workload can read and write, so the SDK or CLI caches the access token once and reuses it.

### No public JWK was registered for the issuer

Authentication fails with `No public JWK was registered for issuer ... and subject ...`. Despite the wording, this error usually means the `aud` claim is wrong rather than the `sub` claim. W\&B uses `aud` to find the organization, then looks for the issuer within that organization. When `aud` doesn't name a W\&B organization, no issuer matches and the error names the `sub` from the token.

Check the `aud` claim first against [Audience requirements](#audience-requirements). On Multi-tenant Cloud, `aud` must contain exactly one value, the organization name. Then confirm that the `iss` value exactly matches an issuer URL in **Settings** > **Authentication**, including the scheme and any trailing path.

### Recreating a deleted service account fails with a duplicate entry error

Deleting an external service account leaves its issuer and subject pair claimed. Creating a new one with the same JWT issuer and the same **Subject** fails with a database error naming a duplicate entry.

Create the replacement with a different subject. For a Kubernetes workload, give the Kubernetes service account a new name, which changes `sub` to `system:serviceaccount:<namespace>:<new-name>`. If you must reuse the original subject, contact [support](mailto:support@wandb.com).

### Public API calls fail or return nothing

Calls through `wandb.Api()` fail or return empty results. Support for identity federation in the [Public API](/models/ref/python/public-api) was added in a later SDK release than support for `wandb.init()`. An older SDK raises a usage error or sends the access token in a form the server rejects. Upgrade to the latest `wandb` SDK.
