---
title: Usar WIF com o Microsoft Entra ID
url: https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure
description: Federe identidades gerenciadas do Azure e o Entra Workload Identity com a Claude API para que suas cargas de trabalho do Azure possam chamar o Claude sem chaves de API estáticas.
---

As cargas de trabalho do Azure se autenticam na Claude API apresentando um "JSON Web Token" (token web JSON), ou JWT, emitido pelo Microsoft Entra ID e, em seguida, trocando-o por um token de acesso da Anthropic de curta duração. A configuração segue o mesmo formato em todas as plataformas do Azure:

1. **Registrar o audience do token:** Crie um "app registration" (registro de aplicativo) no seu "tenant" (locatário) do Microsoft Entra para representar o "audience" (público-alvo) da Claude API. Toda carga de trabalho no locatário solicita tokens do Entra para ele.
2. **Configurar a identidade para sua plataforma:** Uma "managed identity" (identidade gerenciada) em VMs, VM Scale Sets, App Service, Functions e Container Apps, ou o Entra Workload Identity no AKS.
3. **Configurar a Anthropic:** Registre o emissor do Entra do seu locatário, crie uma "service account" (conta de serviço) e escreva uma "federation rule" (regra de federação) que corresponda às "claims" (declarações) do token.
4. **Trocar em tempo de execução:** Sua carga de trabalho troca seu token emitido pelo Entra em `POST /v1/oauth/token` por um token de acesso da Anthropic `sk-ant-oat01-...` e chama o Claude com ele.

Em ambos os caminhos, o token que você apresenta à Anthropic carrega o emissor do Entra específico do seu locatário e o ID de objeto da identidade gerenciada nas claims `sub` e `oid`; apenas a forma como a carga de trabalho obtém esse token difere. Escolha a seção correspondente ao local onde sua carga de trabalho é executada: [Usar uma identidade gerenciada](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#use-a-managed-identity) para VMs, VM Scale Sets, App Service, Functions ou Container Apps; [Usar o Entra Workload Identity no AKS](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#use-entra-workload-identity-on-aks) para AKS.

## Pré-requisitos

* Familiaridade com os [conceitos de WIF](https://platform.claude.com/docs/pt-BR/manage-claude/workload-identity-federation#concepts): contas de serviço, emissores de federação e regras de federação.
* Uma assinatura do Azure com permissão para atribuir identidades gerenciadas (ou configurar o Entra Workload Identity no AKS).
* Permissão para criar um registro de aplicativo e uma "service principal" (entidade de serviço) no seu locatário do Microsoft Entra (o audience compartilhado da Claude API). O Entra só emite tokens para um audience que exista no locatário, portanto a etapa [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience) é obrigatória antes que qualquer solicitação de token seja bem-sucedida.
* O ID do seu locatário do Microsoft Entra. Encontre-o no portal do Azure em **Microsoft Entra ID → Overview → Tenant ID**.
* Permissão para criar contas de serviço, emissores de federação e regras de federação no Claude Console para sua organização da Anthropic.

## Registrar o audience do token

O Microsoft Entra ID só emite um token quando o audience solicitado existe no seu locatário como um registro de aplicativo com uma entidade de serviço. Crie um registro de aplicativo para representar o audience da Claude API; toda carga de trabalho no locatário pode solicitar tokens para ele. Sem esse registro, as solicitações de token falham com um erro "resource not found in tenant" (`AADSTS50001` nos endpoints de identidade gerenciada, `AADSTS500011` no endpoint de token do Entra).

```bash
# Crie o registro de aplicativo que representa a audiência da Claude API.
APP_ID=$(az ad app create --display-name claude-api-federation --query appId -o tsv)

# Solicite tokens de acesso v2.0 e defina o URI identificador api://<APP_ID>.
az ad app update --id "$APP_ID" \
  --identifier-uris "api://$APP_ID" \
  --set api.requestedAccessTokenVersion=2

# Crie a entidade de serviço para que a audiência seja resolvida no seu locatário.
az ad sp create --id "$APP_ID"
```

<Note>
  Use o formato de URI de identificador `api://<APP_ID>`. O Entra restringe URIs de identificador `https://` a domínios verificados do seu próprio locatário, portanto uma URI como `https://api.anthropic.com` não pode ser registrada na maioria dos locatários; `api://<APP_ID>` é aceita em todos os lugares. Com `requestedAccessTokenVersion: 2`, os tokens para esse audience são v2.0, que é o que este guia pressupõe. Se você reutilizar um registro existente que emite tokens v1.0, consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
</Note>

## Usar uma identidade gerenciada

Use este caminho quando sua carga de trabalho é executada em uma VM, um VM Scale Set, App Service, Functions ou Container Apps. A carga de trabalho solicita um JWT emitido pelo Entra para sua identidade gerenciada atribuída a partir do endpoint de token local da plataforma e, em seguida, troca esse JWT com a Anthropic.

### Configurar a identidade gerenciada

<Steps>
  <Step title="Anexar uma identidade gerenciada">
    Habilite uma identidade gerenciada atribuída pelo sistema ou atribuída pelo usuário no seu recurso do Azure. No portal do Azure, abra o recurso, vá para **Identity** e ative **System assigned** (ou anexe uma identidade atribuída pelo usuário).

    Depois que a identidade for criada, anote seu **Object (principal) ID**. Esse GUID aparece tanto na claim `sub` quanto na claim `oid` do token emitido, e sua regra de federação da Anthropic fará a correspondência com ele. Você pode encontrá-lo na página **Identity** do recurso; para uma identidade atribuída pelo usuário, é o **Object (principal) ID** na página **Overview** do recurso de identidade gerenciada. (Uma identidade gerenciada tem apenas uma entidade de serviço no Microsoft Entra ID, não um registro de aplicativo.)
  </Step>

  <Step title="Encontrar o endpoint de token da plataforma">
    A plataforma expõe um endpoint de token local assim que a identidade é anexada:

    * **VMs e VM Scale Sets:** IMDS em `http://169.254.169.254/metadata/identity/oauth2/token` com o cabeçalho `Metadata: true` e `api-version=2018-02-01`.
    * **App Service, Functions e Container Apps:** A URL na variável de ambiente `IDENTITY_ENDPOINT` com o cabeçalho `X-IDENTITY-HEADER` definido com o valor de `IDENTITY_HEADER`, e `api-version=2019-08-01`. O IMDS não é acessível nessas plataformas.

    Se o recurso tiver mais de uma identidade gerenciada atribuída pelo usuário, adicione `client_id=<IDENTITY_CLIENT_ID>` à solicitação de token para selecionar uma. O Azure recomenda sempre especificá-lo. Sem ele, o resultado depende de o recurso também ter uma identidade atribuída pelo sistema habilitada: se tiver, a solicitação recai silenciosamente nessa identidade e então falha na correspondência de `oid` da sua regra de federação; se não tiver, a solicitação falha imediatamente assim que uma segunda identidade atribuída pelo usuário é anexada.
  </Step>

  <Step title="Decodificar um token de exemplo">
    Solicite um token ao endpoint e decodifique seu payload para confirmar as claims com as quais sua regra de federação precisa corresponder. (Para o comando de decodificação, consulte [Solucionar problemas de uma troca com falha](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference#troubleshoot-a-failed-exchange).) Um token v2.0 para uma identidade gerenciada carrega estas claims:

    ```json
    {
      "iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
      "sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "aud": "<APP_ID>",
      "oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "tid": "<TENANT_ID>",
      "azp": "<IDENTITY_CLIENT_ID>",
      "ver": "2.0",
      "exp": 1775527120
    }
    ```

    | Claim | Valor                                                                                                                                                                                                              | Faça a correspondência quando                                                                                                                                                                                                   |
    | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `oid` | O ID de objeto da identidade gerenciada, idêntico a `sub`                                                                                                                                                          | Você quer autorizar uma identidade gerenciada específica. Este é o padrão; a regra em [Configurar a Anthropic](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#configure-anthropic) corresponde a ele. |
    | `azp` | O ID do cliente da identidade chamadora                                                                                                                                                                            | Você quer autorizar toda carga de trabalho que compartilha um registro de aplicativo. Para uma identidade gerenciada, `azp` é exclusivo dessa identidade, portanto é equivalente a `oid`.                                       |
    | `aud` | O ID do cliente do registro de aplicativo do audience (o GUID `<APP_ID>` de [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience)) | Sempre. O campo `audience` da regra deve ser exatamente igual ao valor `aud` do token.                                                                                                                                          |
    | `tid` | O ID do seu locatário                                                                                                                                                                                              | Você quer defesa em profundidade. A URL do emissor já fixa o locatário.                                                                                                                                                         |

    Se a claim `ver` do token decodificado for `1.0`, os nomes e valores das claims diferem. Consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0) antes de continuar.
  </Step>
</Steps>

### Configurar a Anthropic

No Claude Console, vá para a página [Workload identity](https://platform.claude.com/settings/workload-identity-federation) (`platform.claude.com/settings/workload-identity-federation`), clique em **Connect workload** e selecione o bloco **Microsoft Entra**. O assistente orienta você no registro do emissor, na criação de uma conta de serviço e na criação de uma regra de federação.

O assistente cria esses recursos para você. Use os seguintes valores, seja inserindo-os no assistente ou enviando-os para a [Admin API](https://platform.claude.com/docs/pt-BR/manage-claude/wif-admin-api):

**Emissor de federação:** Escolha **v2.0 (login.microsoftonline.com)** no seletor **Token issuer** do assistente. (O seletor tem v1 como padrão; esse padrão existe para locatários que reutilizam registros mais antigos que ainda emitem tokens v1.0.) O Entra publica um documento de descoberta OIDC na URL do emissor por locatário, portanto use o modo de descoberta. Cada locatário do Microsoft Entra que você federar precisa de seu próprio registro de emissor.

```json
{
  "name": "azure-prod-tenant",
  "issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
  "jwks": { "type": "discovery" },
  "max_jwt_lifetime_seconds": 86400
}
```

<Warning>
  Cargas de trabalho com identidade gerenciada precisam de `max_jwt_lifetime_seconds: 86400`. O Azure emite tokens de identidade gerenciada com até 24 horas entre `iat` e `exp` porque armazena em cache o token de cada recurso durante essa janela e não oferece nenhuma forma de forçar uma atualização antecipada, e o padrão de 1 hora do emissor rejeita esses tokens, de modo que a troca falha com a resposta opaca `401` `authentication_error` (mensagem `Authentication failed`). O bloco Microsoft Entra do assistente Connect workload cria o emissor com `max_jwt_lifetime_seconds` definido como `7500` e não fornece nenhum campo para alterá-lo durante a criação; portanto, conclua o assistente, depois abra a aba **Issuers** na página [Workload identity](https://platform.claude.com/settings/workload-identity-federation) no Claude Console, edite o emissor e aumente o valor para `86400`. Você também pode atualizar o emissor por meio da Admin API.
</Warning>

Um tempo de vida aceito mais longo significa que um token do Entra vazado permanece trocável por mais tempo. Se um token vazar, a alavanca é desabilitar a regra de federação; uma correspondência restrita de `oid` limita quais identidades podem trocar um token em primeiro lugar, conforme descrito em [Delimitar o escopo da sua regra](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#scope-your-rule).

**Regra de federação:** Faça a correspondência com o ID de objeto da identidade gerenciada e o ID do seu locatário. Para os tokens v2.0 que este guia configura, o valor de `audience` é o ID do cliente do registro de aplicativo do audience (o GUID `<APP_ID>` de [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience)). Use o valor `aud` exato do seu token decodificado.

```json
{
  "name": "azure-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "audience": "<APP_ID>",
    "claims": {
      "oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "tid": "<TENANT_ID>"
    }
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}
```

`token_lifetime_seconds` é o tempo de vida do token de acesso da Anthropic que a troca retorna, não do token do Entra; o SDK o atualiza para você.

### Adquirir e usar o token

Em tempo de execução, sua carga de trabalho busca seu token do Entra, troca-o em `POST /v1/oauth/token` e usa o token bearer retornado para chamar o Claude. O SDK do Claude cuida do ciclo de troca e atualização quando você fornece `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`), conforme mostrado nos exemplos a seguir. Exceto em Java (consulte o comentário nesse exemplo), essa opção recebe um provedor de token, e o SDK o chama novamente a cada atualização. A aba cURL mostra o fluxo bruto.

Os exemplos buscam o token de identidade gerenciada no endpoint de token da plataforma: IMDS em VMs e VM Scale Sets, ou o serviço `IDENTITY_ENDPOINT` no App Service, Functions e Container Apps. Substitua `<APP_ID>` no valor de recurso `api://<APP_ID>` pelo ID do cliente do registro de aplicativo do audience de [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience).

<Tip>
  Se sua carga de trabalho já usa a biblioteca de cliente Azure Identity, obtenha o token do Entra a partir dela (`DefaultAzureCredential` com o escopo `api://<APP_ID>/.default`) em vez de chamar os endpoints de token diretamente. Forneça-o a `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`) da mesma forma que os exemplos fazem. A biblioteca seleciona o endpoint correto em todas as plataformas do Azure, incluindo o AKS com o Entra Workload Identity.
</Tip>

<CodeGroup>
  ```bash cURL
  # 1. Obtenha o token emitido pelo Entra (identidade gerenciada).
  #    Em uma VM ou VM Scale Set, use o IMDS. Com várias identidades atribuídas
  #    pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
  ENTRA_TOKEN=$(curl -sS -H "Metadata: true" \
    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=api://<APP_ID>" \
    | jq -r .access_token)

  #    No App Service, Functions ou Container Apps, use o serviço de token local
  #    em vez disso (o IMDS não é acessível nesses ambientes):
  # ENTRA_TOKEN=$(curl -sS -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" \
  #   "$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=api://<APP_ID>" \
  #   | jq -r .access_token)

  #    Para AKS com Entra Workload Identity, use a troca em duas etapas da
  #    seção "Use Entra Workload Identity on AKS" em vez disso.

  # 2. Troque-o por um token de acesso da Anthropic.
  RESPONSE=$(curl -sS https://api.anthropic.com/v1/oauth/token \
    -H "content-type: application/json" \
    -d @- <<JSON
  {
    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion": "$ENTRA_TOKEN",
    "federation_rule_id": "$ANTHROPIC_FEDERATION_RULE_ID",
    "organization_id": "$ANTHROPIC_ORGANIZATION_ID",
    "service_account_id": "$ANTHROPIC_SERVICE_ACCOUNT_ID",
    "workspace_id": "$ANTHROPIC_WORKSPACE_ID"
  }
  JSON
  )

  ACCESS_TOKEN=$(echo "$RESPONSE" | jq -r .access_token)

  # 3. Chame a Claude API com o bearer token.
  curl https://api.anthropic.com/v1/messages \
    -H "authorization: Bearer $ACCESS_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "messages": [{"role": "user", "content": "Hello from Azure"}]
    }' | jq -r '.content[] | select(.type == "text") | .text'
  ```

  ```python Python
  import os

  import anthropic
  import requests
  from anthropic import WorkloadIdentityCredentials

  # O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
  AUDIENCE = "api://<APP_ID>"


  def fetch_entra_token() -> str:
      """Fetch a managed identity token from the platform's token endpoint."""
      # Com várias identidades atribuídas pelo usuário, adicione client_id=<IDENTITY_CLIENT_ID>
      # aos parâmetros da requisição para selecionar uma.
      if endpoint := os.environ.get("IDENTITY_ENDPOINT"):
          # App Service, Functions, Container Apps
          response = requests.get(
              endpoint,
              headers={"X-IDENTITY-HEADER": os.environ["IDENTITY_HEADER"]},
              params={"api-version": "2019-08-01", "resource": AUDIENCE},
              timeout=5,
          )
      else:
          # VM ou VM Scale Set: Azure Instance Metadata Service (IMDS)
          response = requests.get(
              "http://169.254.169.254/metadata/identity/oauth2/token",
              headers={"Metadata": "true"},
              params={"api-version": "2018-02-01", "resource": AUDIENCE},
              timeout=5,
          )
      response.raise_for_status()
      return response.json()["access_token"]


  client = anthropic.Anthropic(
      credentials=WorkloadIdentityCredentials(
          identity_token_provider=fetch_entra_token,
          federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
          organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
          service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
          workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
      ),
  )

  message = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello from Azure"}],
  )
  print(next(block.text for block in message.content if block.type == "text"))
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";
  import { oidcFederationProvider } from "@anthropic-ai/sdk/lib/credentials/oidc-federation";

  // O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
  const AUDIENCE = "api://<APP_ID>";

  async function fetchEntraToken(): Promise<string> {
    // App Service, Functions e Container Apps injetam IDENTITY_ENDPOINT;
    // VMs e VM Scale Sets usam IMDS.
    // Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
    const identityEndpoint = process.env.IDENTITY_ENDPOINT;
    const url = identityEndpoint
      ? `${identityEndpoint}?api-version=2019-08-01&resource=${AUDIENCE}`
      : `http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=${AUDIENCE}`;
    const headers: Record<string, string> = identityEndpoint
      ? { "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER! }
      : { Metadata: "true" };
    const response = await fetch(url, { headers });
    const body = (await response.json()) as { access_token: string };
    return body.access_token;
  }

  const client = new Anthropic({
    credentials: oidcFederationProvider({
      identityTokenProvider: fetchEntraToken,
      federationRuleId: process.env.ANTHROPIC_FEDERATION_RULE_ID!,
      organizationId: process.env.ANTHROPIC_ORGANIZATION_ID!,
      serviceAccountId: process.env.ANTHROPIC_SERVICE_ACCOUNT_ID,
      workspaceId: process.env.ANTHROPIC_WORKSPACE_ID,
      baseURL: "https://api.anthropic.com",
      fetch
    })
  });

  const message = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello from Azure" }]
  });
  for (const block of message.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```go Go
  package main

  import (
  	"context"
  	"encoding/json"
  	"fmt"
  	"net/http"
  	"os"

  	"github.com/anthropics/anthropic-sdk-go"
  	"github.com/anthropics/anthropic-sdk-go/option"
  )

  // O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
  const audience = "api://<APP_ID>"

  // fetchEntraToken obtém um token de identidade gerenciada do endpoint de token da
  // plataforma: IMDS em VMs e VM Scale Sets, ou o serviço IDENTITY_ENDPOINT
  // no App Service, Functions e Container Apps.
  func fetchEntraToken(ctx context.Context) (string, error) {
  	// Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
  	tokenURL := "http://169.254.169.254/metadata/identity/oauth2/token" +
  		"?api-version=2018-02-01&resource=" + audience
  	header, value := "Metadata", "true"
  	if endpoint := os.Getenv("IDENTITY_ENDPOINT"); endpoint != "" {
  		tokenURL = endpoint + "?api-version=2019-08-01&resource=" + audience
  		header, value = "X-IDENTITY-HEADER", os.Getenv("IDENTITY_HEADER")
  	}
  	req, err := http.NewRequestWithContext(ctx, http.MethodGet, tokenURL, nil)
  	if err != nil {
  		return "", err
  	}
  	req.Header.Set(header, value)
  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return "", fmt.Errorf("call token endpoint: %w", err)
  	}
  	defer resp.Body.Close()
  	var body struct {
  		AccessToken string `json:"access_token"`
  	}
  	if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
  		return "", fmt.Errorf("decode token response: %w", err)
  	}
  	return body.AccessToken, nil
  }

  func main() {
  	client := anthropic.NewClient(
  		option.WithFederationTokenProvider(fetchEntraToken, option.FederationOptions{
  			FederationRuleID: os.Getenv("ANTHROPIC_FEDERATION_RULE_ID"),
  			OrganizationID:   os.Getenv("ANTHROPIC_ORGANIZATION_ID"),
  			ServiceAccountID: os.Getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"),
  			WorkspaceID:      os.Getenv("ANTHROPIC_WORKSPACE_ID"),
  		}),
  	)

  	message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 1024,
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock("Hello from Azure")),
  		},
  	})
  	if err != nil {
  		panic(err)
  	}
  	for _, block := range message.Content {
  		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  			fmt.Println(textBlock.Text)
  			break
  		}
  	}
  }
  ```

  ```java Java
  import com.anthropic.config.AuthenticationConfig;
  import com.anthropic.config.AuthenticationType;
  import com.anthropic.config.IdentityTokenConfig;
  import com.anthropic.config.InMemoryProfileConfigProvider;
  import com.anthropic.config.ProfileConfig;
  // ...
  import com.fasterxml.jackson.databind.ObjectMapper;
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;

  void main() throws Exception {
      HttpClient http = HttpClient.newHttpClient();
      // O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
      String audience = "api://<APP_ID>";
      // App Service, Functions e Container Apps injetam IDENTITY_ENDPOINT;
      // VMs e VM Scale Sets usam IMDS.
      // Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
      String identityEndpoint = System.getenv("IDENTITY_ENDPOINT");
      HttpRequest tokenRequest = identityEndpoint != null
              ? HttpRequest.newBuilder(URI.create(identityEndpoint + "?api-version=2019-08-01&resource=" + audience))
                      .header("X-IDENTITY-HEADER", System.getenv("IDENTITY_HEADER"))
                      .build()
              : HttpRequest.newBuilder(URI.create("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=" + audience))
                      .header("Metadata", "true")
                      .build();

      // O SDK Java recebe o próprio token ou um caminho de arquivo, não uma função; com
      // source("value"), path(...) contém o token. O SDK envia esse mesmo token
      // a cada renovação do token de acesso da Anthropic, o que falha quando ele
      // expira ou, se tiver uma claim jti, já foi usado. Para um processo de longa duração,
      // passe source("file") e grave um novo token no arquivo antes de
      // cada renovação.
      var response = http.send(tokenRequest, HttpResponse.BodyHandlers.ofString());
      String entraToken = new ObjectMapper().readTree(response.body()).get("access_token").asText();

      AnthropicClient client = AnthropicOkHttpClient.builder()
              .configurationProvider(InMemoryProfileConfigProvider.of(ProfileConfig.builder()
                      .organizationId(System.getenv("ANTHROPIC_ORGANIZATION_ID"))
                      .workspaceId(System.getenv("ANTHROPIC_WORKSPACE_ID"))
                      .authentication(AuthenticationConfig.builder()
                              .type(AuthenticationType.OIDC_FEDERATION)
                              .federationRuleId(System.getenv("ANTHROPIC_FEDERATION_RULE_ID"))
                              .serviceAccountId(System.getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"))
                              .identityToken(IdentityTokenConfig.builder()
                                      .source("value")
                                      .path(entraToken)
                                      .build())
                              .build())
                      .build()))
              .build();

      var message = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello from Azure")
              .build());

      IO.println(message.content());
  }
  ```

  ```csharp C#
  using Anthropic.Credentials;
  // ...

  var credentials = new WorkloadIdentityCredentials(new WorkloadIdentityOptions
  {
      FederationRuleId = Environment.GetEnvironmentVariable("ANTHROPIC_FEDERATION_RULE_ID")!,
      OrganizationId = Environment.GetEnvironmentVariable("ANTHROPIC_ORGANIZATION_ID"),
      ServiceAccountId = Environment.GetEnvironmentVariable("ANTHROPIC_SERVICE_ACCOUNT_ID"),
      WorkspaceId = Environment.GetEnvironmentVariable("ANTHROPIC_WORKSPACE_ID"),
      IdentityTokenProvider = new EntraTokenProvider(),
  });
  using var client = new AnthropicClient(new ClientOptions { Credentials = credentials });

  var message = await client.Messages.Create(new()
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Messages = [new() { Role = Role.User, Content = "Hello from Azure" }],
  });
  foreach (var block in message.Content)
  {
      if (block.Value is TextBlock textBlock)
      {
          Console.WriteLine(textBlock.Text);
      }
  }

  class EntraTokenProvider : IIdentityTokenProvider
  {
      // O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
      private const string Audience = "api://<APP_ID>";

      private static readonly HttpClient httpClient = new();

      public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
      {
          // App Service, Functions e Container Apps injetam IDENTITY_ENDPOINT;
          // VMs e VM Scale Sets usam IMDS.
          // Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
          var identityEndpoint = Environment.GetEnvironmentVariable("IDENTITY_ENDPOINT");
          using var request = identityEndpoint is not null
              ? new HttpRequestMessage(HttpMethod.Get,
                  $"{identityEndpoint}?api-version=2019-08-01&resource={Audience}")
              {
                  Headers = { { "X-IDENTITY-HEADER", Environment.GetEnvironmentVariable("IDENTITY_HEADER") } },
              }
              : new HttpRequestMessage(HttpMethod.Get,
                  $"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource={Audience}")
              {
                  Headers = { { "Metadata", "true" } },
              };
          using var response = await httpClient.SendAsync(request, ct);
          response.EnsureSuccessStatusCode();
          using var json = await JsonDocument.ParseAsync(
              await response.Content.ReadAsStreamAsync(ct), default, ct);
          return json.RootElement.GetProperty("access_token").GetString()!;
      }
  }
  ```

  ```php PHP
  use Anthropic\Client;
  use Anthropic\Lib\Credentials\CredentialResult;
  use Anthropic\Lib\Credentials\IdentityTokenProvider;
  use Anthropic\Lib\Credentials\TokenCache;
  use Anthropic\Lib\Credentials\WorkloadIdentityCredentials;

  // O URI de identificador do registro de aplicativo do público (consulte Registrar o público do token).
  const AUDIENCE = 'api://<APP_ID>';

  class EntraIdentityToken implements IdentityTokenProvider
  {
      public function getIdentityToken(): string
      {
          // App Service, Functions e Container Apps injetam IDENTITY_ENDPOINT;
          // VMs e VM Scale Sets usam IMDS.
          // Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
          $identityEndpoint = getenv('IDENTITY_ENDPOINT');
          if ($identityEndpoint !== false) {
              $url = $identityEndpoint . '?api-version=2019-08-01&resource=' . AUDIENCE;
              $header = 'X-IDENTITY-HEADER: ' . getenv('IDENTITY_HEADER');
          } else {
              $url = 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=' . AUDIENCE;
              $header = 'Metadata: true';
          }
          $context = stream_context_create([
              'http' => ['header' => $header . "\r\n"],
          ]);
          $body = json_decode(file_get_contents($url, false, $context), true);
          return $body['access_token'];
      }
  }

  $credentials = new CredentialResult(
      provider: new TokenCache(new WorkloadIdentityCredentials(
          identityProvider: new EntraIdentityToken(),
          federationRuleId: getenv('ANTHROPIC_FEDERATION_RULE_ID'),
          organizationId: getenv('ANTHROPIC_ORGANIZATION_ID'),
          serviceAccountId: getenv('ANTHROPIC_SERVICE_ACCOUNT_ID'),
          workspaceId: getenv('ANTHROPIC_WORKSPACE_ID') ?: null,
      )),
  );
  $client = new Client(credentials: $credentials);

  $message = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello from Azure']],
  );
  $textBlock = array_find($message->content, static fn ($block): bool => $block->type === 'text');
  echo $textBlock->text, PHP_EOL;
  ```

  ```ruby Ruby
  require "anthropic"
  require "json"
  require "net/http"

  # O URI de identificador do registro de app do público (veja Registrar o público do token).
  AUDIENCE = "api://<APP_ID>"

  def fetch_entra_token
    # App Service, Functions e Container Apps injetam IDENTITY_ENDPOINT;
    # VMs e VM Scale Sets usam IMDS.
    # Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
    if (endpoint = ENV["IDENTITY_ENDPOINT"])
      url = "#{endpoint}?api-version=2019-08-01&resource=#{AUDIENCE}"
      headers = {"X-IDENTITY-HEADER" => ENV.fetch("IDENTITY_HEADER")}
    else
      url = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=#{AUDIENCE}"
      headers = {"Metadata" => "true"}
    end
    response = Net::HTTP.get(URI(url), headers)
    JSON.parse(response).fetch("access_token")
  end

  credentials = Anthropic::WorkloadIdentityCredentials.new(
    identity_token_provider: -> { fetch_entra_token },
    federation_rule_id: ENV.fetch("ANTHROPIC_FEDERATION_RULE_ID"),
    organization_id: ENV.fetch("ANTHROPIC_ORGANIZATION_ID"),
    service_account_id: ENV.fetch("ANTHROPIC_SERVICE_ACCOUNT_ID"),
    workspace_id: ENV["ANTHROPIC_WORKSPACE_ID"]
  )
  client = Anthropic::Client.new(credentials: credentials)

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello from Azure"}]
  )
  puts message.content.find { it.type == :text }.text
  ```

  ```bash CLI
  # Grave o token de acesso emitido pelo Entra em um arquivo que a CLI possa ler.
  # Exemplo para VM ou VM Scale Set (IMDS). No App Service, Functions ou
  # Container Apps, busque em "$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=api://<APP_ID>"
  # com -H "X-IDENTITY-HEADER: $IDENTITY_HEADER" em vez disso.
  # Com várias identidades atribuídas pelo usuário, acrescente &client_id=<IDENTITY_CLIENT_ID>.
  ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
  trap 'rm -f "$ANTHROPIC_IDENTITY_TOKEN_FILE"' EXIT
  curl -sS -H "Metadata: true" \
    "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=api://<APP_ID>" \
    | jq -r .access_token > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
  export ANTHROPIC_IDENTITY_TOKEN_FILE

  # ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
  # ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID são lidos do ambiente.
  ant messages create \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: "Hello from Azure"}'
  ```
</CodeGroup>

### Verificar a configuração

A partir do seu recurso do Azure, execute a troca cURL mostrada em [Adquirir e usar o token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#acquire-and-use-the-token) e confirme que `POST /v1/oauth/token` retorna um `200` com um `access_token` começando com `sk-ant-oat01-` e um valor `expires_in` em segundos. Se a troca falhar com a resposta opaca `401` `authentication_error` (mensagem `Authentication failed`), verifique a [página de histórico de autenticação](https://platform.claude.com/settings/workload-identity-federation?tab=history) no Claude Console para ver o motivo da negação, depois decodifique o token do Entra (consulte [Solucionar problemas de uma troca com falha](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference#troubleshoot-a-failed-exchange) para o comando) e verifique as causas mais comuns do lado do Azure:

* **Incompatibilidade de emissor:** A `issuer_url` registrada deve corresponder exatamente à claim `iss` do token. Um token v2.0 carrega `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; se a claim `ver` decodificada for `1.0`, consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
* **Tempo de vida do token:** Tokens de identidade gerenciada carregam até 24 horas entre `iat` e `exp`. Se o emissor ainda tiver o `7500` do assistente (ou o padrão de 1 hora), aumente `max_jwt_lifetime_seconds` para `86400` conforme descrito em [Configurar a Anthropic](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#configure-anthropic).
* **Incompatibilidade de audience:** O `audience` da regra deve ser exatamente igual ao `aud` do token: o ID do cliente do registro de aplicativo do audience para os tokens v2.0 que este guia configura.
* **Incompatibilidade de nome de claim:** Uma regra que faz correspondência com uma claim que o token não carrega nunca é aprovada. Tokens v1.0 carregam o ID do cliente em `appid`, não em `azp`; consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).

## Usar o Entra Workload Identity no AKS

Use este caminho quando sua carga de trabalho é executada em um pod do AKS. O Entra Workload Identity federa uma conta de serviço do Kubernetes com uma identidade gerenciada atribuída pelo usuário: o Kubernetes projeta um token de conta de serviço (assinado pelo emissor OIDC do cluster AKS) no pod, no caminho em `AZURE_FEDERATED_TOKEN_FILE`. Esse token projetado não é um token emitido pelo Entra, portanto, para permanecer no caminho mediado pelo Entra descrito nesta página, a carga de trabalho realiza uma troca em dois saltos: primeiro ela resgata o token projetado em `https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token` (concessão `client_credentials` federada) por um token de acesso emitido pelo Entra e, em seguida, passa esse token do Entra ao SDK da Anthropic como o token de identidade.

<Tip>
  Os pods do AKS podem, alternativamente, pular a troca do Entra e apresentar o token de conta de serviço projetado pelo Kubernetes diretamente à Anthropic. Esse caminho registra o emissor OIDC do seu cluster AKS na Anthropic em vez do seu locatário do Entra. Consulte [Usar WIF com Kubernetes](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/kubernetes) para esse fluxo.
</Tip>

### Configurar o Entra Workload Identity

<Steps>
  <Step title="Habilitar o emissor OIDC e o workload identity no seu cluster">
    Habilitar o workload identity instala o webhook de mutação `azure-workload-identity` para você; implante-o manualmente apenas em clusters que não sejam AKS. Capture a URL do emissor OIDC do cluster para a credencial federada que você criará em uma etapa posterior.

    ```bash
    az aks update \
      --resource-group <RESOURCE_GROUP> \
      --name <CLUSTER_NAME> \
      --enable-oidc-issuer \
      --enable-workload-identity

    AKS_OIDC_ISSUER=$(az aks show \
      --resource-group <RESOURCE_GROUP> \
      --name <CLUSTER_NAME> \
      --query oidcIssuerProfile.issuerUrl -o tsv)
    ```
  </Step>

  <Step title="Criar uma identidade gerenciada atribuída pelo usuário">
    Capture dois valores da identidade: o **Client ID** vai na anotação da conta de serviço (e é injetado no pod como `AZURE_CLIENT_ID`), e o **Object (principal) ID** aparece como a claim `oid` com a qual sua regra de federação da Anthropic faz correspondência.

    ```bash
    az identity create \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --location <LOCATION>

    # Vai na anotação da service account; injetado no pod como AZURE_CLIENT_ID.
    IDENTITY_CLIENT_ID=$(az identity show \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --query clientId -o tsv)

    # Aparece como a claim oid que sua regra de federação corresponde.
    IDENTITY_OBJECT_ID=$(az identity show \
      --resource-group <RESOURCE_GROUP> \
      --name claude-inference-identity \
      --query principalId -o tsv)
    ```
  </Step>

  <Step title="Criar a conta de serviço do Kubernetes anotada">
    O webhook `azure-workload-identity` lê a anotação `azure.workload.identity/client-id` para injetar `AZURE_CLIENT_ID` no pod, que os exemplos em [Adquirir e usar o token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) leem do ambiente.

    ```yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: claude-inference
      namespace: inference
      annotations:
        azure.workload.identity/client-id: <IDENTITY_CLIENT_ID>
    ```
  </Step>

  <Step title="Criar a credencial federada na identidade gerenciada">
    A credencial federada confia no emissor OIDC do seu cluster para essa conta de serviço específica. O valor `--audience api://AzureADTokenExchange` é o audience fixo do Entra para tokens de conta de serviço do Kubernetes recebidos; ele não tem relação com o audience da Claude API que você registrou anteriormente.

    ```bash
    az identity federated-credential create \
      --resource-group <RESOURCE_GROUP> \
      --identity-name claude-inference-identity \
      --name claude-inference-aks \
      --issuer "$AKS_OIDC_ISSUER" \
      --subject system:serviceaccount:inference:claude-inference \
      --audience api://AzureADTokenExchange
    ```
  </Step>

  <Step title="Rotular o pod e definir sua conta de serviço">
    O pod deve carregar o rótulo `azure.workload.identity/use: "true"` e ser executado como a conta de serviço anotada. O webhook então injeta `AZURE_FEDERATED_TOKEN_FILE`, `AZURE_CLIENT_ID` e `AZURE_TENANT_ID` no pod. O arquivo em `AZURE_FEDERATED_TOKEN_FILE` contém o token de conta de serviço projetado pelo Kubernetes, assinado pelo emissor OIDC do cluster AKS.

    ```yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: inference-worker
      namespace: inference
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: claude-inference
      containers:
        - name: app
          image: your-registry/inference-worker:latest
    ```
  </Step>

  <Step title="Decodificar um token de exemplo">
    O token que sua regra de federação da Anthropic vê não é o arquivo projetado; é o token emitido pelo Entra retornado pela troca `client_credentials`. De dentro de um pod rotulado, execute a etapa 1 do exemplo cURL em [Adquirir e usar o token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) e decodifique o resultado. Ele carrega o mesmo formato de claims do caminho de identidade gerenciada:

    ```json
    {
      "iss": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
      "sub": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "aud": "<APP_ID>",
      "oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "tid": "<TENANT_ID>",
      "azp": "<IDENTITY_CLIENT_ID>",
      "ver": "2.0",
      "exp": 1775527120
    }
    ```

    `sub` e `oid` são o ID de objeto da identidade gerenciada, `aud` é o ID do cliente do registro de aplicativo do audience, e `azp` é o ID do cliente da identidade gerenciada (o valor de `AZURE_CLIENT_ID`). O tempo de vida difere do caminho de identidade gerenciada: tokens `client_credentials` têm como padrão uma janela aleatória de 60 a 90 minutos entre `iat` e `exp`, não 24 horas.
  </Step>
</Steps>

### Configurar a Anthropic

No Claude Console, vá para a página [Workload identity](https://platform.claude.com/settings/workload-identity-federation) (`platform.claude.com/settings/workload-identity-federation`), clique em **Connect workload** e selecione o bloco **Microsoft Entra**. O assistente orienta você no registro do emissor, na criação de uma conta de serviço e na criação de uma regra de federação.

O assistente cria esses recursos para você. Use os seguintes valores, seja inserindo-os no assistente ou enviando-os para a [Admin API](https://platform.claude.com/docs/pt-BR/manage-claude/wif-admin-api):

**Emissor de federação:** Escolha **v2.0 (login.microsoftonline.com)** no seletor **Token issuer** do assistente. (O seletor tem v1 como padrão; esse padrão existe para locatários que reutilizam registros mais antigos que ainda emitem tokens v1.0.) O Entra publica um documento de descoberta OIDC na URL do emissor por locatário, portanto use o modo de descoberta. Cada locatário do Microsoft Entra que você federar precisa de seu próprio registro de emissor.

```json
{
  "name": "azure-prod-tenant",
  "issuer_url": "https://login.microsoftonline.com/<TENANT_ID>/v2.0",
  "jwks": { "type": "discovery" },
  "max_jwt_lifetime_seconds": 7500
}
```

<Warning>
  O bloco Microsoft Entra do assistente Connect workload cria o emissor com `max_jwt_lifetime_seconds` definido como `7500` (pouco mais de 2 horas), o que cobre o tempo de vida padrão de 60 a 90 minutos dos tokens `client_credentials`. Uma política de tempo de vida de token do locatário ou a Continuous Access Evaluation (CAE) pode estender esse tempo de vida. Se o `exp` menos `iat` do seu token decodificado exceder 7500 segundos, edite o emissor na aba **Issuers** da página [Workload identity](https://platform.claude.com/settings/workload-identity-federation) no Claude Console e aumente `max_jwt_lifetime_seconds` para corresponder; caso contrário, as trocas falham com a resposta opaca `401` `authentication_error` (mensagem `Authentication failed`). Se seu locatário também executa cargas de trabalho com identidade gerenciada de [Usar uma identidade gerenciada](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#use-a-managed-identity), use o valor `86400` daquela seção, que cobre ambos os caminhos.
</Warning>

Um tempo de vida aceito mais longo significa que um token do Entra vazado permanece trocável por mais tempo. Se um token vazar, a alavanca é desabilitar a regra de federação; uma correspondência restrita de `oid` limita quais identidades podem trocar um token em primeiro lugar, conforme descrito em [Delimitar o escopo da sua regra](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#scope-your-rule).

**Regra de federação:** Faça a correspondência com o ID de objeto da identidade gerenciada e o ID do seu locatário. Para os tokens v2.0 que este guia configura, o valor de `audience` é o ID do cliente do registro de aplicativo do audience (o GUID `<APP_ID>` de [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience)). Use o valor `aud` exato do seu token decodificado.

```json
{
  "name": "azure-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "audience": "<APP_ID>",
    "claims": {
      "oid": "9f8e7d6c-1a2b-3c4d-5e6f-...",
      "tid": "<TENANT_ID>"
    }
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}
```

`token_lifetime_seconds` é o tempo de vida do token de acesso da Anthropic que a troca retorna, não do token do Entra; o SDK o atualiza para você.

### Adquirir e usar o token

Em tempo de execução, o pod realiza a troca em dois saltos: envia o token projetado pelo Kubernetes (o arquivo em `AZURE_FEDERATED_TOKEN_FILE`) ao endpoint de token do Entra como uma asserção `client_credentials` federada e, em seguida, troca o token de acesso do Entra resultante em `POST /v1/oauth/token`. O SDK do Claude cuida da segunda troca e do ciclo de atualização quando você fornece `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`), conforme mostrado nos exemplos a seguir. Exceto em Java (consulte o comentário nesse exemplo), essa opção recebe sua busca do Entra como um provedor de token, e o SDK a chama novamente a cada atualização. A aba cURL mostra o fluxo bruto.

Dois IDs de cliente diferentes aparecem nos exemplos. `<APP_ID>` é o ID do cliente do registro de aplicativo do audience de [Registrar o audience do token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#register-the-token-audience); o escopo `api://<APP_ID>/.default` pede ao Entra um token endereçado a esse audience. `$AZURE_CLIENT_ID` é o ID do cliente da identidade gerenciada, injetado pelo webhook, e identifica o chamador. Não substitua um pelo outro.

<Tip>
  Se sua carga de trabalho já usa a biblioteca de cliente Azure Identity, obtenha o token do Entra a partir dela (`DefaultAzureCredential` com o escopo `api://<APP_ID>/.default`) em vez de realizar você mesmo a troca em dois saltos. Forneça-o a `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`) da mesma forma que os exemplos fazem. A biblioteca lê as mesmas variáveis de ambiente `AZURE_FEDERATED_TOKEN_FILE`, `AZURE_CLIENT_ID` e `AZURE_TENANT_ID` e cuida da troca com o Entra.
</Tip>

<CodeGroup>
  ```bash cURL
  # 1. Troque o token projetado pelo Kubernetes (em $AZURE_FEDERATED_TOKEN_FILE)
  #    por um JWT emitido pelo Entra.
  ENTRA_JWT=$(curl -sS "https://login.microsoftonline.com/$AZURE_TENANT_ID/oauth2/v2.0/token" \
    -d grant_type=client_credentials \
    -d "client_id=$AZURE_CLIENT_ID" \
    --data-urlencode "scope=api://<APP_ID>/.default" \
    -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
    --data-urlencode "client_assertion@$AZURE_FEDERATED_TOKEN_FILE" \
    | jq -r .access_token)

  # 2. Troque o JWT do Entra por um token de acesso da Anthropic.
  ACCESS_TOKEN=$(curl -sS https://api.anthropic.com/v1/oauth/token \
    -H "content-type: application/json" \
    -d @- <<JSON | jq -r .access_token
  {
    "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
    "assertion": "$ENTRA_JWT",
    "federation_rule_id": "$ANTHROPIC_FEDERATION_RULE_ID",
    "organization_id": "$ANTHROPIC_ORGANIZATION_ID",
    "service_account_id": "$ANTHROPIC_SERVICE_ACCOUNT_ID",
    "workspace_id": "$ANTHROPIC_WORKSPACE_ID"
  }
  JSON
  )

  # 3. Chame a API do Claude.
  curl -sS https://api.anthropic.com/v1/messages \
    -H "authorization: Bearer $ACCESS_TOKEN" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d '{
      "model": "claude-opus-5-5",
      "max_tokens": 1024,
      "messages": [{"role": "user", "content": "Hello from Azure"}]
    }' | jq -r '.content[] | select(.type == "text") | .text'
  ```

  ```python Python
  import os
  from pathlib import Path

  import anthropic
  import requests
  from anthropic import WorkloadIdentityCredentials


  def fetch_entra_token_via_federation() -> str:
      federated_token = Path(os.environ["AZURE_FEDERATED_TOKEN_FILE"]).read_text()
      response = requests.post(
          f"https://login.microsoftonline.com/{os.environ['AZURE_TENANT_ID']}/oauth2/v2.0/token",
          data={
              "client_id": os.environ["AZURE_CLIENT_ID"],
              "grant_type": "client_credentials",
              "scope": "api://<APP_ID>/.default",
              "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
              "client_assertion": federated_token,
          },
          timeout=5,
      )
      response.raise_for_status()
      return response.json()["access_token"]


  client = anthropic.Anthropic(
      credentials=WorkloadIdentityCredentials(
          identity_token_provider=fetch_entra_token_via_federation,
          federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
          organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
          service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
          workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
      ),
  )

  message = client.messages.create(
      model="claude-opus-5-5",
      max_tokens=1024,
      messages=[{"role": "user", "content": "Hello from Azure"}],
  )
  print(next(block.text for block in message.content if block.type == "text"))
  ```

  ```typescript TypeScript
  import Anthropic from "@anthropic-ai/sdk";
  import { oidcFederationProvider } from "@anthropic-ai/sdk/lib/credentials/oidc-federation";
  import { readFile } from "node:fs/promises";

  async function fetchEntraTokenViaFederation(): Promise<string> {
    const federatedToken = await readFile(process.env.AZURE_FEDERATED_TOKEN_FILE!, "utf8");
    const response = await fetch(
      `https://login.microsoftonline.com/${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`,
      {
        method: "POST",
        headers: { "content-type": "application/x-www-form-urlencoded" },
        body: new URLSearchParams({
          client_id: process.env.AZURE_CLIENT_ID!,
          grant_type: "client_credentials",
          scope: "api://<APP_ID>/.default",
          client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
          client_assertion: federatedToken
        })
      }
    );
    const body = (await response.json()) as { access_token: string };
    return body.access_token;
  }

  const client = new Anthropic({
    credentials: oidcFederationProvider({
      identityTokenProvider: fetchEntraTokenViaFederation,
      federationRuleId: process.env.ANTHROPIC_FEDERATION_RULE_ID!,
      organizationId: process.env.ANTHROPIC_ORGANIZATION_ID!,
      serviceAccountId: process.env.ANTHROPIC_SERVICE_ACCOUNT_ID,
      workspaceId: process.env.ANTHROPIC_WORKSPACE_ID,
      baseURL: "https://api.anthropic.com",
      fetch
    })
  });

  const message = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "Hello from Azure" }]
  });
  for (const block of message.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  ```

  ```go Go
  package main

  import (
  	"context"
  	"encoding/json"
  	"fmt"
  	"net/http"
  	"net/url"
  	"os"
  	"strings"

  	"github.com/anthropics/anthropic-sdk-go"
  	"github.com/anthropics/anthropic-sdk-go/option"
  )

  func fetchEntraTokenViaFederation(ctx context.Context) (string, error) {
  	federatedToken, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE"))
  	if err != nil {
  		return "", err
  	}
  	form := url.Values{
  		"client_id":             {os.Getenv("AZURE_CLIENT_ID")},
  		"grant_type":            {"client_credentials"},
  		"scope":                 {"api://<APP_ID>/.default"},
  		"client_assertion_type": {"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
  		"client_assertion":      {strings.TrimSpace(string(federatedToken))},
  	}
  	tokenURL := "https://login.microsoftonline.com/" + os.Getenv("AZURE_TENANT_ID") + "/oauth2/v2.0/token"
  	req, err := http.NewRequestWithContext(ctx, http.MethodPost, tokenURL, strings.NewReader(form.Encode()))
  	if err != nil {
  		return "", err
  	}
  	req.Header.Set("content-type", "application/x-www-form-urlencoded")
  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		return "", err
  	}
  	defer resp.Body.Close()
  	var body struct {
  		AccessToken string `json:"access_token"`
  	}
  	if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
  		return "", err
  	}
  	return body.AccessToken, nil
  }

  func main() {
  	client := anthropic.NewClient(
  		option.WithFederationTokenProvider(option.IdentityTokenFunc(fetchEntraTokenViaFederation), option.FederationOptions{
  			FederationRuleID: os.Getenv("ANTHROPIC_FEDERATION_RULE_ID"),
  			OrganizationID:   os.Getenv("ANTHROPIC_ORGANIZATION_ID"),
  			ServiceAccountID: os.Getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"),
  			WorkspaceID:      os.Getenv("ANTHROPIC_WORKSPACE_ID"),
  		}),
  	)
  	message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 1024,
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock("Hello from Azure")),
  		},
  	})
  	if err != nil {
  		panic(err)
  	}
  	for _, block := range message.Content {
  		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  			fmt.Println(textBlock.Text)
  			break
  		}
  	}
  }
  ```

  ```java Java
  import com.anthropic.config.AuthenticationConfig;
  import com.anthropic.config.AuthenticationType;
  import com.anthropic.config.IdentityTokenConfig;
  import com.anthropic.config.InMemoryProfileConfigProvider;
  import com.anthropic.config.ProfileConfig;
  // ...
  import com.fasterxml.jackson.databind.ObjectMapper;
  import java.net.URI;
  import java.net.URLEncoder;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.util.Map;
  import java.util.stream.Collectors;
  import static java.nio.charset.StandardCharsets.UTF_8;

  void main() throws Exception {
      var form = Map.of(
                      "client_id", System.getenv("AZURE_CLIENT_ID"),
                      "grant_type", "client_credentials",
                      "scope", "api://<APP_ID>/.default",
                      "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
                      "client_assertion", Files.readString(Path.of(System.getenv("AZURE_FEDERATED_TOKEN_FILE"))))
              .entrySet().stream()
              .map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), UTF_8))
              .collect(Collectors.joining("&"));
      var request = HttpRequest.newBuilder(URI.create(
                      "https://login.microsoftonline.com/" + System.getenv("AZURE_TENANT_ID") + "/oauth2/v2.0/token"))
              .header("content-type", "application/x-www-form-urlencoded")
              .POST(HttpRequest.BodyPublishers.ofString(form))
              .build();

      // O SDK Java recebe o próprio token ou um caminho de arquivo, não uma função; com
      // source("value"), path(...) contém o token. O SDK envia esse mesmo token
      // a cada renovação do token de acesso da Anthropic, o que falha quando ele
      // expira ou, se tiver uma claim jti, já foi usado. Para um processo de longa duração,
      // passe source("file") e grave um novo token no arquivo antes de
      // cada renovação.
      var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
      String entraToken = new ObjectMapper().readTree(response.body()).get("access_token").asText();

      AnthropicClient client = AnthropicOkHttpClient.builder()
              .configurationProvider(InMemoryProfileConfigProvider.of(ProfileConfig.builder()
                      .organizationId(System.getenv("ANTHROPIC_ORGANIZATION_ID"))
                      .workspaceId(System.getenv("ANTHROPIC_WORKSPACE_ID"))
                      .authentication(AuthenticationConfig.builder()
                              .type(AuthenticationType.OIDC_FEDERATION)
                              .federationRuleId(System.getenv("ANTHROPIC_FEDERATION_RULE_ID"))
                              .serviceAccountId(System.getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"))
                              .identityToken(IdentityTokenConfig.builder()
                                      .source("value")
                                      .path(entraToken)
                                      .build())
                              .build())
                      .build()))
              .build();

      var message = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello from Azure")
              .build());

      IO.println(message.content());
  }
  ```

  ```csharp C#
  using Anthropic.Credentials;
  // ...

  var credentials = new WorkloadIdentityCredentials(new WorkloadIdentityOptions
  {
      FederationRuleId = Environment.GetEnvironmentVariable("ANTHROPIC_FEDERATION_RULE_ID")!,
      OrganizationId = Environment.GetEnvironmentVariable("ANTHROPIC_ORGANIZATION_ID"),
      ServiceAccountId = Environment.GetEnvironmentVariable("ANTHROPIC_SERVICE_ACCOUNT_ID"),
      WorkspaceId = Environment.GetEnvironmentVariable("ANTHROPIC_WORKSPACE_ID"),
      IdentityTokenProvider = new EntraFederationTokenProvider(),
  });
  using var client = new AnthropicClient(new ClientOptions { Credentials = credentials });

  var message = await client.Messages.Create(new()
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Messages = [new() { Role = Role.User, Content = "Hello from Azure" }],
  });
  foreach (var block in message.Content)
  {
      if (block.Value is TextBlock textBlock)
      {
          Console.WriteLine(textBlock.Text);
      }
  }

  class EntraFederationTokenProvider : IIdentityTokenProvider
  {
      private static readonly HttpClient Http = new();

      public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
      {
          var federatedToken = await File.ReadAllTextAsync(
              Environment.GetEnvironmentVariable("AZURE_FEDERATED_TOKEN_FILE")!, ct);
          var tenantId = Environment.GetEnvironmentVariable("AZURE_TENANT_ID");
          var form = new FormUrlEncodedContent(new Dictionary<string, string>
          {
              ["client_id"] = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID")!,
              ["grant_type"] = "client_credentials",
              ["scope"] = "api://<APP_ID>/.default",
              ["client_assertion_type"] = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
              ["client_assertion"] = federatedToken,
          });
          var response = await Http.PostAsync(
              $"https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token", form, ct);
          response.EnsureSuccessStatusCode();
          using var json = await JsonDocument.ParseAsync(
              await response.Content.ReadAsStreamAsync(ct), default, ct);
          return json.RootElement.GetProperty("access_token").GetString()!;
      }
  }
  ```

  ```php PHP
  use Anthropic\Client;
  use Anthropic\Lib\Credentials\CredentialResult;
  use Anthropic\Lib\Credentials\IdentityTokenProvider;
  use Anthropic\Lib\Credentials\TokenCache;
  use Anthropic\Lib\Credentials\WorkloadIdentityCredentials;

  class EntraIdentityTokenViaFederation implements IdentityTokenProvider
  {
      public function getIdentityToken(): string
      {
          $ch = curl_init('https://login.microsoftonline.com/' . getenv('AZURE_TENANT_ID') . '/oauth2/v2.0/token');
          curl_setopt_array($ch, [
              CURLOPT_RETURNTRANSFER => true,
              CURLOPT_POSTFIELDS => http_build_query([
                  'client_id' => getenv('AZURE_CLIENT_ID'),
                  'grant_type' => 'client_credentials',
                  'scope' => 'api://<APP_ID>/.default',
                  'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
                  'client_assertion' => file_get_contents(getenv('AZURE_FEDERATED_TOKEN_FILE')),
              ]),
          ]);
          $body = json_decode(curl_exec($ch), true);
          curl_close($ch);
          return $body['access_token'];
      }
  }

  $client = new Client(
      credentials: new CredentialResult(
          provider: new TokenCache(new WorkloadIdentityCredentials(
              identityProvider: new EntraIdentityTokenViaFederation(),
              federationRuleId: getenv('ANTHROPIC_FEDERATION_RULE_ID'),
              organizationId: getenv('ANTHROPIC_ORGANIZATION_ID'),
              serviceAccountId: getenv('ANTHROPIC_SERVICE_ACCOUNT_ID'),
              workspaceId: getenv('ANTHROPIC_WORKSPACE_ID') ?: null,
          )),
      ),
  );

  $message = $client->messages->create(
      model: 'claude-opus-5-5',
      maxTokens: 1024,
      messages: [['role' => 'user', 'content' => 'Hello from Azure']],
  );
  $textBlock = array_find($message->content, static fn ($block): bool => $block->type === 'text');
  echo $textBlock->text, PHP_EOL;
  ```

  ```ruby Ruby
  require "anthropic"
  require "json"
  require "net/http"

  def fetch_entra_token_via_federation
    tenant_id = ENV.fetch("AZURE_TENANT_ID")
    federated_token = File.read(ENV.fetch("AZURE_FEDERATED_TOKEN_FILE"))
    response = Net::HTTP.post_form(
      URI("https://login.microsoftonline.com/#{tenant_id}/oauth2/v2.0/token"),
      "client_id" => ENV.fetch("AZURE_CLIENT_ID"),
      "grant_type" => "client_credentials",
      "scope" => "api://<APP_ID>/.default",
      "client_assertion_type" => "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
      "client_assertion" => federated_token
    )
    JSON.parse(response.body).fetch("access_token")
  end

  client = Anthropic::Client.new(
    credentials: Anthropic::WorkloadIdentityCredentials.new(
      identity_token_provider: -> { fetch_entra_token_via_federation },
      federation_rule_id: ENV.fetch("ANTHROPIC_FEDERATION_RULE_ID"),
      organization_id: ENV.fetch("ANTHROPIC_ORGANIZATION_ID"),
      service_account_id: ENV.fetch("ANTHROPIC_SERVICE_ACCOUNT_ID"),
      workspace_id: ENV["ANTHROPIC_WORKSPACE_ID"]
    )
  )

  message = client.messages.create(
    model: "claude-opus-5-5",
    max_tokens: 1024,
    messages: [{role: "user", content: "Hello from Azure"}]
  )
  puts message.content.find { it.type == :text }.text
  ```

  ```bash CLI
  # 1. Troque o token projetado pelo Kubernetes por um token de acesso emitido pelo Entra
  # e grave-o em um arquivo temporário que a CLI possa ler.
  ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
  trap 'rm -f "$ANTHROPIC_IDENTITY_TOKEN_FILE"' EXIT
  curl -sS "https://login.microsoftonline.com/$AZURE_TENANT_ID/oauth2/v2.0/token" \
    -d client_id="$AZURE_CLIENT_ID" \
    -d grant_type=client_credentials \
    --data-urlencode "scope=api://<APP_ID>/.default" \
    -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
    --data-urlencode client_assertion@"$AZURE_FEDERATED_TOKEN_FILE" \
    | jq -r .access_token > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
  export ANTHROPIC_IDENTITY_TOKEN_FILE

  # 2. Chame a API do Claude. ANTHROPIC_FEDERATION_RULE_ID,
  # ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID e ANTHROPIC_WORKSPACE_ID são lidos
  # do ambiente.
  ant messages create \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: "Hello from Azure"}'
  ```
</CodeGroup>

### Verificar a configuração

De dentro de um pod rotulado, execute a troca cURL mostrada em [Adquirir e usar o token](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#acquire-and-use-the-token-2) e confirme que `POST /v1/oauth/token` retorna um `200` com um `access_token` começando com `sk-ant-oat01-` e um valor `expires_in` em segundos. Se a troca falhar com a resposta opaca `401` `authentication_error` (mensagem `Authentication failed`), verifique a [página de histórico de autenticação](https://platform.claude.com/settings/workload-identity-federation?tab=history) no Claude Console para ver o motivo da negação, depois decodifique o token emitido pelo Entra da etapa 1 (consulte [Solucionar problemas de uma troca com falha](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference#troubleshoot-a-failed-exchange) para o comando) e verifique as causas mais comuns do lado do Azure:

* **Incompatibilidade de emissor:** A `issuer_url` registrada deve corresponder exatamente à claim `iss` do token. Um token v2.0 carrega `https://login.microsoftonline.com/<TENANT_ID>/v2.0`; se a claim `ver` decodificada for `1.0`, consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).
* **Tempo de vida do token:** Se uma política de tempo de vida de token do locatário ou a CAE estender o token `client_credentials` para além de 7500 segundos, aumente o `max_jwt_lifetime_seconds` do emissor conforme descrito em [Configurar a Anthropic](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#configure-anthropic-2).
* **Incompatibilidade de audience:** O `audience` da regra deve ser exatamente igual ao `aud` do token: o ID do cliente do registro de aplicativo do audience para os tokens v2.0 que este guia configura.
* **Incompatibilidade de nome de claim:** Uma regra que faz correspondência com uma claim que o token não carrega nunca é aprovada. Tokens v1.0 carregam o ID do cliente em `appid`, não em `azp`; consulte [Se seus tokens são v1.0](https://platform.claude.com/docs/pt-BR/manage-claude/wif-providers/azure#if-your-tokens-are-v1-0).

## Se seus tokens são v1.0

Este guia configura o registro de aplicativo do audience com `api.requestedAccessTokenVersion: 2`, portanto todo token que ele mostra é v2.0. Se você reutilizar um registro existente que deixa `requestedAccessTokenVersion` sem definição, o Entra emite tokens v1.0 em vez disso. Decodifique um token de exemplo e verifique sua claim `ver`; se for `1.0`, quatro coisas mudam:

* **Emissor:** A claim `iss` é `https://sts.windows.net/<TENANT_ID>/` em vez de `https://login.microsoftonline.com/<TENANT_ID>/v2.0`. Registre a URL do emissor exatamente como a claim `iss` do seu token a carrega. As duas URLs compartilham o mesmo JWKS, portanto o modo de descoberta funciona para qualquer uma delas.
* **Seletor do assistente:** Escolha **v1 (sts.windows.net)** no seletor **Token issuer** do assistente Connect workload em vez de **v2.0 (login.microsoftonline.com)**.
* **Audience:** A claim `aud` é a URI de identificador que você passou como `resource` (por exemplo, `api://<APP_ID>`), não o ID do cliente do registro. Defina o `audience` da regra de federação com o valor `aud` exato do seu token decodificado.
* **Claim de ID do cliente:** O ID do cliente da identidade chamadora aparece em `appid`, não em `azp`. As duas claims nunca aparecem no mesmo token, portanto uma regra que faz correspondência com `azp` nunca é aprovada contra um token v1.0.

As claims `oid`, `sub` e `tid` carregam os mesmos valores em ambas as versões, portanto o restante deste guia se aplica sem alterações.

## Delimitar o escopo da sua regra

Uma regra de federação pode fazer correspondência com o subject do token usando `subject_prefix` além do (ou em vez do) mapa `claims`; consulte [Semântica de correspondência de regras](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference#rule-matching-semantics) para saber como os campos se combinam. Os valores `sub` do Entra para essas identidades são GUIDs canônicos de comprimento fixo, portanto um `subject_prefix` contendo o ID de objeto completo de 36 caracteres corresponde apenas a esse subject; essa é uma propriedade do formato de subject do Entra, não de `subject_prefix` em geral.

<Warning>
  Toda identidade no seu locatário pode solicitar um token para o audience registrado, portanto `audience` e `tid` sozinhos não identificam uma carga de trabalho específica. Uma regra que omite uma correspondência de `oid` (ou `azp`/`appid`), ou que usa um `subject_prefix` curinga ou de GUID parcial, autoriza toda identidade gerenciada e entidade de serviço no locatário.
</Warning>

Restrinja o bloco `match` da regra ao escopo mais estreito que atenda ao seu caso de uso:

* **Corresponder `oid` como um valor exato:** Defina `claims.oid` com o ID de objeto completo da identidade gerenciada. Um `subject_prefix` definido com esse ID de objeto completo é equivalente (o assistente do Console define ambos); nunca use um `subject_prefix` curinga ou de GUID parcial, que corresponde a mais identidades do que você pretende.
* **Fixar `tid` como defesa em profundidade:** A URL do emissor já fixa seu locatário, mas adicionar `claims.tid` protege contra desvios de configuração caso o registro do emissor seja editado posteriormente.
* **Fixar o audience:** Defina `audience` com o valor `aud` exato do seu token decodificado para que tokens emitidos para outros aplicativos sejam rejeitados.
* **Usar uma regra separada para cada identidade gerenciada:** Crie uma regra para cada identidade em vez de uma regra que autorize várias, para que você possa revogar o acesso de uma única carga de trabalho sem afetar as outras.

## Próximos passos

* Revise o modelo de configuração completo em [Workload Identity Federation](https://platform.claude.com/docs/pt-BR/manage-claude/workload-identity-federation).
* Consulte os [guias de provedores](https://platform.claude.com/docs/pt-BR/manage-claude/workload-identity-federation#identity-providers) para AWS, Google Cloud, GitHub Actions e Kubernetes.
* Para variáveis de ambiente, arquivos de perfil e precedência de credenciais, consulte a [referência de WIF](https://platform.claude.com/docs/pt-BR/manage-claude/wif-reference).
