Follow Discord
Sweep 06 Nov 2026 · 01:32Z Build v2.1.319 537 read Stable v2.1.311 Latest v2.1.319 Next v2.1.319 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

Create the app registration that represents the Claude API audience. changedmanage-claude/wif-providers/azure

Nearest release: v2.1.319, published 17 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+44added
Lines−44removed
From line 7 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits20to this page, all time

The whole hunk

from line 7, old and new numbered
/
lines
from line 7
77Azure workloads authenticate to the Claude API by presenting a JSON Web Token (JWT) issued by Microsoft Entra ID, then exchanging it for a short-lived Anthropic access token. The setup follows the same shape on every Azure platform:
88 
991. **Register the token audience:** Create one app registration in your Microsoft Entra tenant to represent the Claude API audience. Every workload in the tenant requests Entra tokens for it.
102. **Set up the identity for your platform:** Use a managed identity on VMs, VM Scale Sets, App Service, Functions, and Container Apps, or Entra Workload Identity on AKS.
102. **Set up the identity for your platform:** Use a managed identity on VMs, VM Scale Sets, App Service, Functions, and Container Apps, or Entra Workload Identity on Azure Kubernetes Service (AKS).
11113. **Configure Anthropic:** Register your tenant’s Entra issuer, create a service account, and write a federation rule that matches the token’s claims.
12124. **Exchange at runtime:** Your workload exchanges its Entra-issued token at `POST /v1/oauth/token` for an `sk-ant-oat01-...` Anthropic access token and calls Claude with it.
1313 
14On both paths the token you present to Anthropic carries your tenant-specific Entra issuer and the managed identity’s object ID in the `sub` and `oid` claims; only how the workload obtains that token differs. Pick the section for where your workload runs: [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity) for VMs, VM Scale Sets, App Service, Functions, and Container Apps, or [Use Entra Workload Identity on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-entra-workload-identity-on-aks) for AKS.
14On both paths the token you present to Anthropic carries your tenant-specific Entra issuer and the managed identity’s object ID in the `sub` and `oid` claims. Only how the workload obtains that token differs. For VMs, VM Scale Sets, App Service, Functions, and Container Apps, see [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity). For AKS, see [Use Entra Workload Identity on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-entra-workload-identity-on-aks).
1515 
1616## Prerequisites
1717 
18* Familiarity with [WIF concepts](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#concepts): service accounts, federation issuers, and federation rules.
18* Familiarity with [Workload Identity Federation (WIF) concepts](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#concepts): service accounts, federation issuers, and federation rules.
1919* An Azure subscription with permission to assign managed identities (or configure Entra Workload Identity on AKS).
2020* Permission to create one app registration and service principal in your Microsoft Entra tenant (the shared Claude API audience). Entra only issues tokens for an audience that exists in the tenant, so the [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience) step is required before any token request succeeds.
2121* Your Microsoft Entra tenant ID. Find it in the Azure portal under **Microsoft Entra ID → Overview → Tenant ID**.
from line 23
2323 
2424## Register the token audience
2525 
26Microsoft Entra ID only issues a token when the requested audience exists in your tenant as an app registration with a service principal. Create one app registration to represent the Claude API audience; every workload in the tenant can request tokens for it. Without this registration, token requests fail with a “resource not found in tenant” error (`AADSTS50001` from the managed identity endpoints, `AADSTS500011` from the Entra token endpoint).
26Microsoft Entra ID only issues a token when the requested audience exists in your tenant as an app registration with a service principal. Create one app registration to represent the Claude API audience. Every workload in the tenant can request tokens for it. Without this registration, token requests fail with a “resource not found in tenant” error (`AADSTS50001` from the managed identity endpoints, `AADSTS500011` from the Entra token endpoint).
2727 
2828```bash
2929# Create the app registration that represents the Claude API audience.
from line 39
3939```
4040 
4141<Note>
42 Use the `api://<APP_ID>` identifier URI format. Entra restricts `https://` identifier URIs to verified domains of your own tenant, so a URI such as `https://api.anthropic.com` cannot be registered in most tenants; `api://<APP_ID>` is accepted everywhere. With `requestedAccessTokenVersion: 2`, tokens for this audience are v2.0, which is what this guide assumes. If you reuse an existing registration that emits v1.0 tokens, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
42 Use the `api://<APP_ID>` identifier URI format. Entra restricts `https://` identifier URIs to verified domains of your own tenant, so you cannot register a URI such as `https://api.anthropic.com` in most tenants. Entra accepts `api://<APP_ID>` everywhere. With `requestedAccessTokenVersion: 2`, tokens for this audience are v2.0, which is what this guide assumes. If you reuse an existing registration that emits v1.0 tokens, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
4343</Note>
4444 
4545## Use a managed identity
from line 52
5252 <Step title="Attach a managed identity">
5353 Enable a system-assigned or user-assigned managed identity on your Azure resource. In the Azure portal, open the resource, go to **Identity**, and turn on **System assigned** (or attach a user-assigned identity).
5454 
55 After the identity is created, note its **Object (principal) ID**. This GUID appears as both the `sub` and `oid` claims in the issued token, and your Anthropic federation rule matches on it. You can find it on the resource’s **Identity** page; for a user-assigned identity, it is the **Object (principal) ID** on the managed identity resource’s **Overview** page. (A managed identity has only a service principal in Microsoft Entra ID, not an app registration.)
55 After you attach the identity, note its **Object (principal) ID**. This GUID appears as both the `sub` and `oid` claims in the issued token, and your Anthropic federation rule matches on it. You can find it on the resource’s **Identity** page. For a user-assigned identity, it is the **Object (principal) ID** on the managed identity resource’s **Overview** page. (A managed identity has only a service principal in Microsoft Entra ID, not an app registration.)
5656 </Step>
5757 
5858 <Step title="Find the platform’s token endpoint">
59 The platform exposes a local token endpoint once the identity is attached:
59 The platform exposes a local token endpoint once you attach the identity:
6060 
61 * **VMs and VM Scale Sets:** IMDS at `http://169.254.169.254/metadata/identity/oauth2/token` with the header `Metadata: true` and `api-version=2018-02-01`.
61 * **VMs and VM Scale Sets:** Azure Instance Metadata Service (IMDS) at `http://169.254.169.254/metadata/identity/oauth2/token` with the header `Metadata: true` and `api-version=2018-02-01`.
6262 * **App Service, Functions, and Container Apps:** The URL in the `IDENTITY_ENDPOINT` environment variable with the header `X-IDENTITY-HEADER` set to the value of `IDENTITY_HEADER`, and `api-version=2019-08-01`. IMDS is not reachable on these platforms.
6363 
64 If the resource has more than one user-assigned managed identity, add `client_id=<IDENTITY_CLIENT_ID>` to the token request to select one. Azure recommends always specifying it. Without it, the outcome depends on whether the resource also has a system-assigned identity enabled: if it does, the request silently falls back to that identity and then fails your federation rule’s `oid` match; if it does not, the request fails outright as soon as a second user-assigned identity is attached.
64 If the resource has more than one user-assigned managed identity, add `client_id=<IDENTITY_CLIENT_ID>` to the token request to select one. Azure recommends always specifying it. Without it, the outcome depends on whether the resource also has a system-assigned identity enabled. If it does, the request silently falls back to that identity and then fails your federation rule’s `oid` match. If it does not, the request fails outright as soon as you attach a second user-assigned identity.
6565 </Step>
6666 
6767 <Step title="Decode a sample token">
from line 82
8282 
8383 | Claim | Value | Match this when |
8484 | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
85 | `oid` | The managed identity’s object ID, identical to `sub` | You want to authorize one specific managed identity. This is the default; the rule in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic) matches it. |
85 | `oid` | The managed identity’s object ID, identical to `sub` | You want to authorize one specific managed identity. This is the default. The rule in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic) matches it. |
8686 | `azp` | The calling identity’s client ID | You want to authorize every workload that shares one app registration. For a managed identity, `azp` is unique to that identity, so it is equivalent to `oid`. |
8787 | `aud` | The audience app registration’s client ID (the `<APP_ID>` GUID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience)) | Always. The rule’s `audience` field must equal the token’s `aud` value exactly. |
8888 | `tid` | Your tenant ID | You want defense in depth. The issuer URL already pins the tenant. |
from line 97
9797 
9898The wizard creates these resources for you. Use the following values whether you enter them in the wizard or send them to the [Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api):
9999 
100**Federation issuer:** Select **v2.0 (login.microsoftonline.com)** in the wizard’s **Token issuer** selector. (The selector defaults to v1; that default exists for tenants reusing older registrations that still emit v1.0 tokens.) Entra publishes an OIDC discovery document at the per-tenant issuer URL, so use discovery mode. Each Microsoft Entra tenant you federate needs its own issuer record.
100**Federation issuer:** Select **v2.0 (login.microsoftonline.com)** in the wizard’s **Token issuer** selector. (The selector defaults to v1. That default serves tenants whose existing registrations emit v1.0 tokens.) Entra publishes an OpenID Connect (OIDC) discovery document at the tenant-specific issuer URL, so use discovery mode. Each Microsoft Entra tenant you federate needs its own issuer record.
101101 
102102```json
103103{
from line 109
109109```
110110 
111111<Warning>
112 Managed identity workloads need `max_jwt_lifetime_seconds: 86400`. Azure issues managed identity tokens with up to 24 hours between `iat` and `exp` because it caches each resource’s token for that window and offers no way to force an early refresh, and the issuer’s 1-hour default rejects those tokens, so the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`). The **Connect workload** wizard’s **Microsoft Entra** tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` and provides no field to change it during creation, so complete the wizard, then open the **Issuers** tab on the [Workload identity](https://platform.claude.com/settings/workload-identity-federation) page in the Claude Console, edit the issuer, and raise the value to `86400`. You can also update the issuer through the Admin API.
112 Managed identity workloads need `max_jwt_lifetime_seconds: 86400`. Azure issues managed identity tokens with up to 24 hours between `iat` and `exp`. It caches each resource’s token for that window and offers no way to force an early refresh. The issuer’s 1-hour default rejects those tokens, so the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`). The **Connect workload** wizard’s **Microsoft Entra** tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` and provides no field to change it during creation. Complete the wizard, then open the **Issuers** tab on the [Workload identity](https://platform.claude.com/settings/workload-identity-federation) page in the Claude Console, edit the issuer, and raise the value to `86400`. You can also update the issuer through the Admin API.
113113</Warning>
114114 
115A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, disable the federation rule; a tight `oid` match limits which identities can exchange a token in the first place, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
115A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, disable the federation rule. A tight `oid` match limits which identities can exchange a token, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
116116 
117117**Federation rule:** Match on the managed identity’s object ID and your tenant ID. For the v2.0 tokens this guide configures, the `audience` value is the audience app registration’s client ID (the `<APP_ID>` GUID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience)). Use the exact `aud` value from your decoded token.
118118 
from line 137
137137}
138138```
139139 
140`token_lifetime_seconds` is the lifetime of the Anthropic access token the exchange returns, not of the Entra token; the SDK refreshes it for you.
140`token_lifetime_seconds` is the lifetime of the Anthropic access token the exchange returns, not of the Entra token. The SDK refreshes the access token for you.
141141 
142142### Acquire and use the token
143143 
144At runtime your workload fetches its Entra token, exchanges it at `POST /v1/oauth/token`, and uses the returned bearer token to call Claude. The Claude SDK handles the exchange and refresh loop when you supply `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`), as shown in the following examples. Except in Java, where `IdentityTokenConfig` takes a token or a file path, that option takes a token provider, and the SDK calls it again for each refresh.
144At runtime your workload fetches its Entra token, exchanges it at `POST /v1/oauth/token`, and uses the returned bearer token to call Claude. The SDK handles the exchange and refresh loop when you supply `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`), as shown in the following examples. Where that option takes a token provider, the SDK calls it again for each refresh.
145145 
146The samples fetch the managed identity token from the platform’s token endpoint: IMDS on VMs and VM Scale Sets, or the `IDENTITY_ENDPOINT` service on App Service, Functions, and Container Apps. Replace `<APP_ID>` in the `api://<APP_ID>` resource value with the audience app registration’s client ID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience).
146The samples fetch the managed identity token from the platform’s token endpoint. That endpoint is IMDS on VMs and VM Scale Sets, or the `IDENTITY_ENDPOINT` service on App Service, Functions, and Container Apps. Replace `<APP_ID>` in the `api://<APP_ID>` resource value with the audience app registration’s client ID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience).
147147 
148148<Tip>
149149 If your workload already uses the Azure Identity client library, get the Entra token from it (`DefaultAzureCredential` with the scope `api://<APP_ID>/.default`) instead of calling the token endpoints directly. Supply it to `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`) the way the examples do. The library selects the correct endpoint on every Azure platform, including AKS with Entra Workload Identity.
from line 616
616616 
617617### Verify the setup
618618 
619From your Azure resource, run the sample in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token). A successful exchange returns a `200` with an `access_token` starting with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason, then decode the Entra token (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes:
619From your Azure resource, run the sample in [Acquire and use the token](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token). A successful exchange returns a `200` with an `access_token` starting with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason. Then decode the Entra token (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes:
620620 
621* **Issuer mismatch:** The registered `issuer_url` must match the token’s `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; if the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
622* **Token lifetime:** Managed identity tokens carry up to 24 hours between `iat` and `exp`. If the issuer still has the wizard’s `7500` (or the 1-hour default), raise `max_jwt_lifetime_seconds` to `86400` as described in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic).
621* **Issuer mismatch:** The registered `issuer_url` must match the token’s `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`. If the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
622* **Token lifetime:** Managed identity tokens carry up to 24 hours between `iat` and `exp`. If the issuer has the wizard’s `7500` (or the 1-hour default), raise `max_jwt_lifetime_seconds` to `86400` as described in [Configure Anthropic](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic).
623623* **Audience mismatch:** The rule’s `audience` must equal the token’s `aud` exactly: the audience app registration’s client ID for the v2.0 tokens this guide configures.
624* **Claim name mismatch:** A rule that matches on a claim the token does not carry never passes. v1.0 tokens carry the client ID in `appid`, not `azp`; see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
624* **Claim name mismatch:** A rule that matches on a claim the token does not carry never passes. A v1.0 token carries the client ID in `appid`, not `azp`. See [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
625625 
626626## Use Entra Workload Identity on AKS
627627 
628Use this path when your workload runs in an AKS pod. Entra Workload Identity federates a Kubernetes service account with a user-assigned managed identity: Kubernetes projects a service account token (signed by the AKS cluster’s OIDC issuer) into the pod at the path in `AZURE_FEDERATED_TOKEN_FILE`. That projected token is not an Entra-issued token, so to stay on the Entra-mediated path described on this page, the workload performs a two-hop exchange. First, it redeems the projected token at `https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token` (federated `client_credentials` grant) for an Entra-issued access token. Then it passes that Entra token to the Anthropic SDK as the identity token.
628Use this path when your workload runs in an AKS pod. Entra Workload Identity federates a Kubernetes service account with a user-assigned managed identity. Kubernetes projects a service account token (signed by the AKS cluster’s OIDC issuer) into the pod at the path in `AZURE_FEDERATED_TOKEN_FILE`. That projected token is not an Entra-issued token. To stay on the Entra-mediated path described on this page, the workload performs a two-hop exchange. First, it redeems the projected token at `https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token` (federated `client_credentials` grant) for an Entra-issued access token. Then it passes that Entra token to the SDK as the identity token.
629629 
630630<Tip>
631631 AKS pods can alternatively skip the Entra exchange and present the Kubernetes-projected service account token to Anthropic directly. That path registers your AKS cluster’s OIDC issuer with Anthropic instead of your Entra tenant. See [Use WIF with Kubernetes](https://platform.claude.com/docs/en/manage-claude/wif-providers/kubernetes) for that flow.
from line 635
635635 
636636<Steps>
637637 <Step title="Enable the OIDC issuer and workload identity on your cluster">
638 Enabling workload identity installs the `azure-workload-identity` mutating webhook for you; deploy it manually only on non-AKS clusters. Capture the cluster’s OIDC issuer URL for the federated credential you create in a later step.
638 Enabling workload identity installs the `azure-workload-identity` mutating webhook for you. Deploy it manually only on non-AKS clusters. Capture the cluster’s OIDC issuer URL for the federated credential you create in a later step.
639639 
640640 ```bash
641641 az aks update \
from line 652
652652 </Step>
653653 
654654 <Step title="Create a user-assigned managed identity">
655 Capture two values from the identity: the **Client ID** goes into the service account annotation (and is injected into the pod as `AZURE_CLIENT_ID`), and the **Object (principal) ID** appears as the `oid` claim that your Anthropic federation rule matches.
655 Capture two values from the identity. The **Client ID** goes into the service account annotation, and the webhook injects it into the pod as `AZURE_CLIENT_ID`. The **Object (principal) ID** appears as the `oid` claim that your Anthropic federation rule matches.
656656 
657657 ```bash
658658 az identity create \
from line 675
675675 </Step>
676676 
677677 <Step title="Create the annotated Kubernetes service account">
678 The `azure-workload-identity` webhook reads the `azure.workload.identity/client-id` annotation to inject `AZURE_CLIENT_ID` into the pod, which the samples in [Acquire and use the token on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) read from the environment.
678 The `azure-workload-identity` webhook reads the `azure.workload.identity/client-id` annotation to inject `AZURE_CLIENT_ID` into the pod. The samples in [Acquire and use the token on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) read it from the environment.
679679 
680680 ```yaml
681681 apiVersion: v1
from line 689
689689 </Step>
690690 
691691 <Step title="Create the federated credential on the managed identity">
692 The federated credential trusts your cluster’s OIDC issuer for that specific service account. The `--audience api://AzureADTokenExchange` value is Entra’s fixed audience for incoming Kubernetes service account tokens; it is unrelated to the Claude API audience you registered earlier.
692 The federated credential trusts your cluster’s OIDC issuer for that specific service account. The `--audience api://AzureADTokenExchange` value is Entra’s fixed audience for incoming Kubernetes service account tokens. It is unrelated to the Claude API audience you registered earlier.
693693 
694694 ```bash
695695 az identity federated-credential create \
from line 722
722722 </Step>
723723 
724724 <Step title="Decode a sample token">
725 The token your Anthropic federation rule sees is not the projected file; it is the Entra-issued token returned by the `client_credentials` exchange. From inside a labeled pod, fetch the Entra token as shown in [Acquire and use the token on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) and decode the result. It carries the same claim shape as the managed identity path:
725 The token your Anthropic federation rule sees is not the projected file. It is the Entra-issued token returned by the `client_credentials` exchange. From inside a labeled pod, fetch the Entra token as shown in [Acquire and use the token on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) and decode the result. It carries the same claim shape as the managed identity path:
726726 
727727 ```json
728728 {
from line 737
737737 }
738738 ```
739739 
740 `sub` and `oid` are the managed identity’s object ID, `aud` is the audience app registration’s client ID, and `azp` is the managed identity’s client ID (the value of `AZURE_CLIENT_ID`). The lifetime differs from the managed identity path: `client_credentials` tokens default to a random 60- to 90-minute window between `iat` and `exp`, not 24 hours.
740 `sub` and `oid` are the managed identity’s object ID, `aud` is the audience app registration’s client ID, and `azp` is the managed identity’s client ID (the value of `AZURE_CLIENT_ID`). The lifetime differs from the managed identity path. `client_credentials` tokens default to a random 60- to 90-minute window between `iat` and `exp`, not 24 hours.
741741 </Step>
742742</Steps>
743743 
from line 747
747747 
748748The wizard creates these resources for you. Use the following values whether you enter them in the wizard or send them to the [Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api):
749749 
750**Federation issuer:** Select **v2.0 (login.microsoftonline.com)** in the wizard’s **Token issuer** selector. (The selector defaults to v1; that default exists for tenants reusing older registrations that still emit v1.0 tokens.) Entra publishes an OIDC discovery document at the per-tenant issuer URL, so use discovery mode. Each Microsoft Entra tenant you federate needs its own issuer record.
750**Federation issuer:** Select **v2.0 (login.microsoftonline.com)** in the wizard’s **Token issuer** selector. (The selector defaults to v1. That default serves tenants whose existing registrations emit v1.0 tokens.) Entra publishes an OIDC discovery document at the tenant-specific issuer URL, so use discovery mode. Each Microsoft Entra tenant you federate needs its own issuer record.
751751 
752752```json
753753{
from line 759
759759```
760760 
761761<Warning>
762 The **Connect workload** wizard’s **Microsoft Entra** tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` (just over 2 hours), which covers the default 60- to 90-minute lifetime of `client_credentials` tokens. A tenant token-lifetime policy or Continuous Access Evaluation (CAE) can extend that lifetime. If your decoded token’s `exp` minus `iat` exceeds 7,500 seconds, edit the issuer on the **Issuers** tab of the [Workload identity](https://platform.claude.com/settings/workload-identity-federation) page in the Claude Console and raise `max_jwt_lifetime_seconds` to match, or exchanges fail with the opaque `401` `authentication_error` response (message `Authentication failed`). If your tenant also runs managed-identity workloads from [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity), use that section’s `86400` value, which covers both paths.
762 The **Connect workload** wizard’s **Microsoft Entra** tile creates the issuer with `max_jwt_lifetime_seconds` set to `7500` (a little over 2 hours). That value covers the default 60- to 90-minute lifetime of `client_credentials` tokens. A tenant token-lifetime policy or Continuous Access Evaluation (CAE) can extend that lifetime. If your decoded token’s `exp` minus `iat` exceeds 7,500 seconds, edit the issuer on the **Issuers** tab of the [Workload identity](https://platform.claude.com/settings/workload-identity-federation) page in the Claude Console and raise `max_jwt_lifetime_seconds` to match. Until you do, exchanges fail with the opaque `401` `authentication_error` response (message `Authentication failed`). If your tenant also runs managed identity workloads from [Use a managed identity](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#use-a-managed-identity), use that section’s `86400` value, which covers both paths.
763763</Warning>
764764 
765A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, disable the federation rule; a tight `oid` match limits which identities can exchange a token in the first place, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
765A longer accepted lifetime means a leaked Entra token stays exchangeable for longer. If a token leaks, disable the federation rule. A tight `oid` match limits which identities can exchange a token, as described in [Scope your rule](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#scope-your-rule).
766766 
767767**Federation rule:** Match on the managed identity’s object ID and your tenant ID. For the v2.0 tokens this guide configures, the `audience` value is the audience app registration’s client ID (the `<APP_ID>` GUID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience)). Use the exact `aud` value from your decoded token.
768768 
from line 787
787787}
788788```
789789 
790`token_lifetime_seconds` is the lifetime of the Anthropic access token the exchange returns, not of the Entra token; the SDK refreshes it for you.
790`token_lifetime_seconds` is the lifetime of the Anthropic access token the exchange returns, not of the Entra token. The SDK refreshes the access token for you.
791791 
792792### Acquire and use the token
793793 
794At runtime the pod performs the two-hop exchange: it sends the Kubernetes-projected token (the file at `AZURE_FEDERATED_TOKEN_FILE`) to Entra’s token endpoint as a federated `client_credentials` assertion, then exchanges the resulting Entra access token at `POST /v1/oauth/token`. The Claude SDK handles the second exchange and the refresh loop when you supply `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`), as shown in the following examples. Except in Java, where `IdentityTokenConfig` takes a token or a file path, that option takes your Entra fetch as a token provider, and the SDK calls it again for each refresh.
794At runtime the pod performs the two-hop exchange. It sends the Kubernetes-projected token (the file at `AZURE_FEDERATED_TOKEN_FILE`) to Entra’s token endpoint as a federated `client_credentials` assertion. It then exchanges the resulting Entra access token at `POST /v1/oauth/token`. The SDK handles the second exchange and the refresh loop when you supply `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`), as shown in the following examples. Where that option takes a token provider, the SDK calls it again for each refresh.
795795 
796Two different client IDs appear in the samples. `<APP_ID>` is the audience app registration’s client ID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience); the scope `api://<APP_ID>/.default` asks Entra for a token addressed to that audience. `$AZURE_CLIENT_ID` is the managed identity’s client ID, injected by the webhook, and identifies the caller. Do not substitute one for the other.
796Two different client IDs appear in the samples. `<APP_ID>` is the audience app registration’s client ID from [Register the token audience](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#register-the-token-audience). The scope `api://<APP_ID>/.default` asks Entra for a token addressed to that audience. `AZURE_CLIENT_ID`, which the webhook injects, is the managed identity’s client ID and identifies the caller. Do not substitute one for the other.
797797 
798798<Tip>
799799 If your workload already uses the Azure Identity client library, get the Entra token from it (`DefaultAzureCredential` with the scope `api://<APP_ID>/.default`) instead of performing the two-hop exchange yourself. Supply it to `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider()`; java: `IdentityTokenConfig`) the way the examples do. The library reads the same `AZURE_FEDERATED_TOKEN_FILE`, `AZURE_CLIENT_ID`, and `AZURE_TENANT_ID` environment variables and handles the Entra exchange.
from line 1247
12471247 
12481248From inside a labeled pod, run the sample in [Acquire and use the token on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#acquire-and-use-the-token-2). A successful exchange returns a `200` with an `access_token` starting with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason. Then decode the Entra-issued token (see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange) for the command) and check the most common Azure-side causes:
12491249 
1250* **Issuer mismatch:** The registered `issuer_url` must match the token’s `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; if the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
1250* **Issuer mismatch:** The registered `issuer_url` must match the token’s `iss` claim exactly. A v2.0 token carries `https://login.microsoftonline.com/<TENANT_ID>/v2.0`. If the decoded `ver` claim is `1.0`, see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
12511251* **Token lifetime:** If a tenant token-lifetime policy or CAE extends the `client_credentials` token past 7,500 seconds, raise the issuer’s `max_jwt_lifetime_seconds` as described in [Configure Anthropic for Entra Workload Identity on AKS](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#configure-anthropic-2).
12521252* **Audience mismatch:** The rule’s `audience` must equal the token’s `aud` exactly: the audience app registration’s client ID for the v2.0 tokens this guide configures.
1253* **Claim name mismatch:** A rule that matches on a claim the token does not carry never passes. v1.0 tokens carry the client ID in `appid`, not `azp`; see [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
1253* **Claim name mismatch:** A rule that matches on a claim the token does not carry never passes. A v1.0 token carries the client ID in `appid`, not `azp`. See [If your tokens are v1.0](https://platform.claude.com/docs/en/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
12541254 
12551255## If your tokens are v1.0
12561256 
1257This guide configures the audience app registration with `api.requestedAccessTokenVersion: 2`, so every token it shows is v2.0. If you reuse an existing registration that leaves `requestedAccessTokenVersion` unset, Entra issues v1.0 tokens instead. Decode a sample token and check its `ver` claim; if it is `1.0`, four things change:
1257This guide configures the audience app registration with `api.requestedAccessTokenVersion: 2`, so every token it shows is v2.0. If you reuse an existing registration that leaves `requestedAccessTokenVersion` unset, Entra issues v1.0 tokens instead. Decode a sample token and check its `ver` claim. If it is `1.0`, four things change:
12581258 
12591259* **Issuer:** The `iss` claim is `https://sts.windows.net/<TENANT_ID>/` instead of `https://login.microsoftonline.com/<TENANT_ID>/v2.0`. Register the issuer URL exactly as your token’s `iss` claim carries it. The two URLs share the same JWKS, so discovery mode works for either.
12601260* **Wizard selector:** Select **v1 (sts.windows.net)** in the **Connect workload** wizard’s **Token issuer** selector instead of **v2.0 (login.microsoftonline.com)**.
from line 1265
12651265 
12661266## Scope your rule
12671267 
1268A federation rule can match the token’s subject with `subject_prefix` in addition to (or instead of) the `claims` map; see [Rule matching semantics](https://platform.claude.com/docs/en/manage-claude/wif-reference#rule-matching-semantics) for how the fields combine. Entra `sub` values for these identities are fixed-length canonical GUIDs, so a `subject_prefix` containing the full 36-character object ID matches only that subject; this is a property of Entra’s subject format, not of `subject_prefix` in general.
1268A federation rule can match the token’s subject with `subject_prefix` in addition to (or instead of) the `claims` map. See [Rule matching semantics](https://platform.claude.com/docs/en/manage-claude/wif-reference#rule-matching-semantics) for how the fields combine. Entra `sub` values for these identities are fixed-length canonical GUIDs, so a `subject_prefix` containing the full 36-character object ID matches only that subject. This is a property of Entra’s subject format, not of `subject_prefix` in general.
12691269 
12701270<Warning>
12711271 Every identity in your tenant can request a token for the registered audience, so `audience` and `tid` alone do not identify a specific workload. A rule that omits an `oid` (or `azp`/`appid`) match, or that uses a wildcard or partial-GUID `subject_prefix`, authorizes every managed identity and service principal in the tenant.
from line 1273
12731273 
12741274Lock the rule’s `match` block to the narrowest scope that fits your use case:
12751275 
1276* **Match `oid` as an exact value:** Set `claims.oid` to the managed identity’s full object ID. A `subject_prefix` set to that full object ID is equivalent (the Console wizard sets both); never use a wildcard or partial-GUID `subject_prefix`, which matches more identities than you intend.
1276* **Match `oid` as an exact value:** Set `claims.oid` to the managed identity’s full object ID. A `subject_prefix` set to that full object ID is equivalent (the Console wizard sets both). Never use a wildcard or partial-GUID `subject_prefix`, which matches more identities than you intend.
12771277* **Pin `tid` as defense in depth:** The issuer URL already pins your tenant, but adding `claims.tid` guards against configuration drift if the issuer record is later edited.
1278* **Pin the audience:** Set `audience` to the exact `aud` value from your decoded token so tokens minted for other applications are rejected.
1278* **Pin the audience:** Set `audience` to the exact `aud` value from your decoded token so the rule rejects tokens issued for other applications.
12791279* **Use a separate rule for each managed identity:** Create one rule for each identity rather than one rule that authorizes several, so you can revoke a single workload’s access without affecting others.
12801280 
12811281## Next steps
12821282 
12831283* Review the full configuration model in [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation).
1284* See the [provider guides](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#identity-providers) for AWS, Google Cloud, GitHub Actions, and Kubernetes.
1284* For AWS, Google Cloud, GitHub Actions, and Kubernetes, see [Identity providers](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#identity-providers).
12851285* For environment variables, profile files, and credential precedence, see the [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference).
12861286 
Feedback