---
title: Utiliser WIF avec Okta
url: https://platform.claude.com/docs/fr/manage-claude/wif-providers/okta
description: Fédérez les identités d'applications de service Okta vers la Claude API avec Workload Identity Federation.
---

Okta peut agir en tant que fournisseur d'identité de charge de travail en émettant des jetons d'accès OIDC à une **application de service** via le flux OAuth 2.0 `client_credentials`. Votre charge de travail s'authentifie auprès d'Okta (généralement avec `private_key_jwt`, de sorte qu'aucun secret partagé n'est stocké), reçoit un « JSON Web Token » (jeton web JSON) signé, ou JWT, et échange ce JWT auprès d'Anthropic contre un jeton d'accès de courte durée.

L'URL d'émetteur du serveur d'autorisation Okta prend la forme `https://<your-domain>.okta.com/oauth2/<auth-server-id>`. Si vous utilisez le serveur par défaut intégré, le chemin est `/oauth2/default`.

<Note>
  Vous devez utiliser un **serveur d'autorisation personnalisé** Okta (y compris celui nommé `default`). Les jetons émis directement par le serveur d'autorisation d'organisation Okta (le point de terminaison `/oauth2/v1/token` sans identifiant de serveur d'autorisation dans le chemin) ne peuvent pas être validés par des tiers, car Okta ne publie pas de clés de signature pour ceux-ci.
</Note>

Il existe de nombreuses façons de configurer Okta et de s'y authentifier qui sortent du cadre de cette documentation. Assurez-vous que vos mécanismes de configuration et d'authentification respectent les directives et les pratiques de sécurité de votre entreprise.

## Prérequis

* Une familiarité avec les [concepts WIF](https://platform.claude.com/docs/fr/manage-claude/workload-identity-federation#concepts) : comptes de service, émetteurs de fédération et règles de fédération.
* Une organisation Okta avec API Access Management activé (requis pour les serveurs d'autorisation personnalisés).
* L'autorisation de créer des comptes de service, des émetteurs de fédération et des règles de fédération dans la Claude Console pour votre organisation Anthropic.
* Une charge de travail capable de demander un jeton au point de terminaison `/v1/token` d'Okta et d'atteindre `api.anthropic.com`.

## Configurer Okta

Dans les grandes lignes, vous devez :

1. Créer une application de service Okta.
2. Configurer votre serveur d'autorisation par défaut (ou créer un nouveau serveur d'autorisation personnalisé) avec une audience, une portée (scope), une politique d'accès et toutes les revendications (claims) personnalisées sur lesquelles vous souhaitez effectuer une correspondance.

La navigation exacte dépend de la configuration de votre organisation Okta et de la version de la console d'administration. Les étapes numérotées suivantes décrivent un parcours courant :

1. **Créez une intégration d'application de service.** Dans la console d'administration Okta, créez une nouvelle intégration d'application de type **API Services** (OIDC, machine à machine). Notez le **Client ID** généré.
2. **Configurez l'authentification du client.** Pour une configuration sans clé, choisissez **Public key / Private key** (`private_key_jwt`) et enregistrez la JWK publique de votre charge de travail. Vous pouvez également utiliser un secret client si votre environnement peut en stocker un de manière sécurisée. Pour l'exemple suivant, vous devrez peut-être désactiver l'exigence DPoP sur l'application ; assurez-vous que votre configuration de production respecte les exigences de sécurité de votre organisation.
3. **Définissez l'audience.** Sur votre serveur d'autorisation personnalisé, définissez l'audience sur `https://api.anthropic.com` afin que les jetons d'accès émis portent cette revendication `aud`. Anthropic valide `aud` par rapport à cette valeur fixe.
4. **Accordez une portée.** Sur votre serveur d'autorisation personnalisé, assurez-vous qu'il existe au moins une portée que l'application de service est autorisée à demander (par exemple, `anthropic.access`). Okta rejette les requêtes `client_credentials` qui n'incluent pas de portée accordée.
5. **Créez une politique d'accès.** Sur votre serveur d'autorisation personnalisé, créez une politique d'accès comportant au moins une règle qui autorise votre application de service à demander la portée accordée à l'étape 4.
6. **(Facultatif) Ajoutez des revendications personnalisées.** Si vous souhaitez effectuer une correspondance sur autre chose que l'identifiant client, ajoutez une revendication au jeton d'accès dans l'onglet **Claims** de votre serveur d'autorisation.

Pour une application de service utilisant `client_credentials`, Okta définit la revendication `sub` du jeton d'accès émis sur le **Client ID** de l'application, et `iss` sur l'URL d'émetteur du serveur d'autorisation.

## Configurer Anthropic

Dans la Claude Console, accédez à la page [Workload identity](https://platform.claude.com/settings/workload-identity-federation) (`platform.claude.com/settings/workload-identity-federation`), cliquez sur **Connect workload**, puis sélectionnez **Custom OIDC**. L'assistant vous guide dans l'enregistrement de l'émetteur, la création d'un compte de service et la création d'une règle de fédération.

L'assistant crée ces ressources pour vous. Utilisez les valeurs suivantes, que vous les saisissiez dans l'assistant ou que vous les envoyiez à l'[Admin API](https://platform.claude.com/docs/fr/manage-claude/wif-admin-api) :

**Émetteur de fédération :** utilisez l'URL de votre serveur d'autorisation personnalisé Okta et le mode de découverte. Anthropic lit le document de découverte `.well-known/openid-configuration` d'Okta et récupère le JWKS à partir du `jwks_uri` qu'il annonce.

```json
{
  "name": "okta-prod",
  "issuer_url": "https://acme.okta.com/oauth2/aus1a2b3c4d5e6f7g8h9",
  "jwks": { "type": "discovery" }
}
```

**Règle de fédération :** effectuez la correspondance sur la revendication `sub` d'Okta, qui correspond au Client ID de l'application de service. Si vous avez défini des revendications personnalisées dans Okta, vous pouvez effectuer la correspondance sur celles-ci à la place avec la map `claims` ou une `condition` CEL.

```json
{
  "name": "okta-pipeline",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "0oa1b2c3d4e5f6g7h8i9",
    "audience": "https://api.anthropic.com"
  },
  "target": { "type": "service_account", "service_account_id": "svac_..." },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}
```

## Obtenir un jeton et appeler la Claude API

Contrairement aux fournisseurs natifs de plateforme (AWS, Google Cloud, Kubernetes), qui mettent un jeton à disposition dans l'environnement d'exécution de la charge de travail (via un fichier projeté ou un point de terminaison de métadonnées local), Okta ne le fait pas. Votre charge de travail doit appeler le point de terminaison de jeton d'Okta pour obtenir un JWT, puis transmettre ce JWT au SDK Anthropic en tant que jeton d'identité.

<CodeGroup>
  ```bash cURL
  # 1. Demandez un jeton d'accès à Okta (client_credentials avec private_key_jwt).
  OKTA_JWT=$(curl -sS "https://acme.okta.com/oauth2/aus1a2b3c4d5e6f7g8h9/v1/token" \
    -d grant_type=client_credentials \
    -d scope=anthropic.access \
    -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
    --data-urlencode client_assertion="$SIGNED_CLIENT_ASSERTION" \
    | jq -r .access_token)

  # 2. Échangez le JWT Okta contre un jeton d'accès 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": "$OKTA_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. Appelez l'API Claude.
  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, Claude"}]}' \
    | jq -r '.content[] | select(.type == "text") | .text'
  ```

  ```python Python
  import os
  import httpx2
  import anthropic
  from anthropic import WorkloadIdentityCredentials


  def fetch_okta_token() -> str:
      response = httpx2.post(
          f"{os.environ['OKTA_ISSUER']}/v1/token",
          data={
              "grant_type": "client_credentials",
              "scope": "anthropic.access",
              "client_assertion_type": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
              # Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
              "client_assertion": build_signed_client_assertion(),
          },
      )
      response.raise_for_status()
      return response.json()["access_token"]


  client = anthropic.Anthropic(
      credentials=WorkloadIdentityCredentials(
          identity_token_provider=fetch_okta_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, Claude"}],
  )
  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";

  async function fetchOktaToken(): Promise<string> {
    const response = await fetch(`${process.env.OKTA_ISSUER}/v1/token`, {
      method: "POST",
      headers: { "content-type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({
        grant_type: "client_credentials",
        scope: "anthropic.access",
        client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
        // Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
        client_assertion: buildSignedClientAssertion()
      })
    });
    const body = (await response.json()) as { access_token: string };
    return body.access_token;
  }

  const client = new Anthropic({
    credentials: oidcFederationProvider({
      identityTokenProvider: fetchOktaToken,
      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, Claude" }]
  });
  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 fetchOktaToken(ctx context.Context) (string, error) {
  	form := url.Values{
  		"grant_type":            {"client_credentials"},
  		"scope":                 {"anthropic.access"},
  		"client_assertion_type": {"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},
  		// Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
  		"client_assertion": {buildSignedClientAssertion()},
  	}
  	req, err := http.NewRequestWithContext(ctx, http.MethodPost,
  		os.Getenv("OKTA_ISSUER")+"/v1/token", 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(fetchOktaToken), 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, Claude")),
  		},
  	})
  	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.util.Map;
  import java.util.stream.Collectors;
  import static java.nio.charset.StandardCharsets.UTF_8;

  void main() throws Exception {
      var form = Map.of(
                      "grant_type", "client_credentials",
                      "scope", "anthropic.access",
                      "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
                      // Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
                      "client_assertion", buildSignedClientAssertion())
              .entrySet().stream()
              .map(entry -> entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), UTF_8))
              .collect(Collectors.joining("&"));
      var request = HttpRequest.newBuilder(URI.create(System.getenv("OKTA_ISSUER") + "/v1/token"))
              .header("content-type", "application/x-www-form-urlencoded")
              .POST(HttpRequest.BodyPublishers.ofString(form))
              .build();

      // Le SDK Java accepte le jeton lui-même ou un chemin de fichier, pas une fonction ; avec
      // source("value"), path(...) contient le jeton. Le SDK envoie ce même jeton
      // à chaque actualisation du jeton d'accès Anthropic, ce qui échoue dès qu'il a
      // expiré ou, s'il possède une revendication jti, été utilisé. Pour un processus
      // de longue durée, passez source("file") et écrivez un nouveau jeton dans le fichier avant
      // chaque actualisation.
      var response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
      String oktaToken = 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(oktaToken)
                                      .build())
                              .build())
                      .build()))
              .build();

      var message = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello, Claude")
              .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 OktaTokenProvider(),
  });
  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, Claude" }],
  });
  foreach (var block in message.Content)
  {
      if (block.Value is TextBlock textBlock)
      {
          Console.WriteLine(textBlock.Text);
      }
  }

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

      public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
      {
          var form = new FormUrlEncodedContent(new Dictionary<string, string>
          {
              ["grant_type"] = "client_credentials",
              ["scope"] = "anthropic.access",
              ["client_assertion_type"] = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
              // Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
              ["client_assertion"] = BuildSignedClientAssertion(),
          });
          var response = await Http.PostAsync(
              $"{Environment.GetEnvironmentVariable("OKTA_ISSUER")}/v1/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()!;
      }
  }
  ```

  ```bash CLI
  # 1. Demandez un jeton d'accès à Okta et écrivez-le dans un fichier temporaire.
  ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
  curl -sS "$OKTA_ISSUER/v1/token" \
    -d grant_type=client_credentials \
    -d scope=anthropic.access \
    -d client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
    --data-urlencode client_assertion="$SIGNED_CLIENT_ASSERTION" \
    | jq -r .access_token > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
  export ANTHROPIC_IDENTITY_TOKEN_FILE

  # 2. Appelez l'API Claude. La CLI lit ANTHROPIC_FEDERATION_RULE_ID,
  # ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID et
  # ANTHROPIC_IDENTITY_TOKEN_FILE, puis effectue l'échange.
  ant messages create \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: "Hello, Claude"}'
  ```

  ```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 OktaIdentityToken implements IdentityTokenProvider
  {
      public function getIdentityToken(): string
      {
          $ch = curl_init(getenv('OKTA_ISSUER') . '/v1/token');
          curl_setopt_array($ch, [
              CURLOPT_RETURNTRANSFER => true,
              CURLOPT_POSTFIELDS => http_build_query([
                  'grant_type' => 'client_credentials',
                  'scope' => 'anthropic.access',
                  'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
                  // Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
                  'client_assertion' => buildSignedClientAssertion(),
              ]),
          ]);
          $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 OktaIdentityToken(),
              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, Claude']],
  );
  echo array_find($message->content, static fn ($block): bool => $block->type === 'text')->text, PHP_EOL;
  ```

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

  def fetch_okta_token
    uri = URI("#{ENV.fetch('OKTA_ISSUER')}/v1/token")
    response = Net::HTTP.post_form(
      uri,
      "grant_type" => "client_credentials",
      "scope" => "anthropic.access",
      "client_assertion_type" => "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
      # Construire le JWT client_assertion RFC 7523 signé avec la clé privée de votre application Okta.
      "client_assertion" => build_signed_client_assertion
    )
    JSON.parse(response.body).fetch("access_token")
  end

  client = Anthropic::Client.new(
    credentials: Anthropic::WorkloadIdentityCredentials.new(
      identity_token_provider: -> { fetch_okta_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"]
    )
  )

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

Sauf en Java (voir le commentaire dans cet exemple), l'exemple SDK transmet votre récupération de jeton Okta à `identity_token_provider` (typescript: `identityTokenProvider`; php: `identityProvider`; csharp: `IdentityTokenProvider`; go: `option.WithFederationTokenProvider`; java: `IdentityTokenConfig`) en tant que fournisseur de jetons. Le SDK Claude l'appelle chaque fois que le jeton d'accès Anthropic approche de son expiration. Votre fonction de récupération Okta doit donc renvoyer un nouveau jeton à chaque appel plutôt que d'en mettre un en cache indéfiniment. La CLI `ant` relit `ANTHROPIC_IDENTITY_TOKEN_FILE` à chaque échange ; actualisez donc ce fichier à intervalles réguliers pour les shells de longue durée.

## Vérifier la configuration

Un échange réussi renvoie un `access_token` commençant par `sk-ant-oat01-` et une valeur `expires_in` en secondes. Si l'échange échoue avec la réponse opaque `401` `authentication_error` (message `Authentication failed`), consultez la [page d'historique d'authentification](https://platform.claude.com/settings/workload-identity-federation?tab=history) dans la Claude Console pour connaître le motif du refus et reportez-vous à [Dépanner un échange échoué](https://platform.claude.com/docs/fr/manage-claude/wif-reference#troubleshoot-a-failed-exchange) ; la cause la plus fréquente côté Okta est une non-concordance de `issuer_url` (elle doit inclure le chemin `/oauth2/<auth-server-id>` ; le serveur d'autorisation d'organisation Okta n'est pas utilisable).

## Restreindre la portée de votre règle

<Warning>
  Plusieurs applications de service relevant du même serveur d'autorisation Okta partagent le même émetteur. Une règle qui omet `subject_prefix` correspond à toutes les applications de service de ce serveur, de sorte que toute équipe pouvant en enregistrer une pourrait obtenir un jeton Anthropic fédéré.
</Warning>

Verrouillez le bloc `match` de la règle sur la portée la plus étroite adaptée à votre cas d'usage :

* **Épinglez le Client ID exact :** définissez `subject_prefix` sur le Client ID complet de l'application de service, sans `*` final.
* **Épinglez l'audience :** faites correspondre la valeur `audience` que vous avez configurée sur le serveur d'autorisation afin que les jetons émis pour une audience différente soient rejetés.
* **Effectuez la correspondance sur des revendications personnalisées :** pour une restriction plus fine, ajoutez des revendications dans l'onglet **Claims** du serveur d'autorisation et faites-les correspondre avec la map `claims` de la règle ou une `condition` CEL.
* **Utilisez une règle par application de service :** créez une règle de fédération distincte pour chaque application de service plutôt que de partager une seule règle entre plusieurs applications.

## Étapes suivantes

* Consultez la [référence WIF](https://platform.claude.com/docs/fr/manage-claude/wif-reference) pour connaître l'ordre complet de résolution des identifiants et la configuration des profils.
* Consultez la [référence WIF](https://platform.claude.com/docs/fr/manage-claude/wif-reference#rule-matching-semantics) pour effectuer une correspondance sur des revendications Okta personnalisées avec des expressions CEL.
