---
title: S'authentifier avec des coffres-forts
url: https://platform.claude.com/docs/fr/managed-agents/vaults
description: Enregistrez des identifiants propres à chaque utilisateur lors de la création de sessions.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

Les coffres-forts (vaults) et les identifiants (credentials) sont des primitives d'authentification qui vous permettent d'enregistrer une seule fois des identifiants pour des services tiers et de les référencer par ID lors de la création d'une session. Cela signifie que vous n'avez pas besoin d'exécuter votre propre magasin de secrets, de transmettre des jetons à chaque appel, ou de perdre la trace de l'utilisateur final pour le compte duquel un agent a agi.

La référence au coffre-fort est un paramètre par session, vous pouvez donc gérer votre produit à la granularité de la ressource `agent` et vos utilisateurs à la granularité de la ressource `session`.

## Créer un coffre-fort

<Warning>
  Les coffres-forts et les identifiants sont limités à l'espace de travail, ce qui signifie que toute clé API ayant accès à l'espace de travail peut les référencer lors de la création d'une session. Pour révoquer l'accès, supprimez le coffre-fort ou l'identifiant.
</Warning>

Un coffre-fort est l'ensemble des `credentials` associés à un utilisateur final. Attribuez-lui un `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) et, éventuellement, étiquetez-le avec des `metadata` (csharp, go: `Metadata`) afin de pouvoir le rattacher à vos propres enregistrements d'utilisateurs.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/vaults \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    --data '{
      "display_name": "Alice",
      "metadata": {"external_user_id": "usr_abc123"}
    }'
  ```

  <CodeGroupItem>
    ```bash CLI
    ant apply vaults/service_accounts.yaml
    ```

    <File filename="vaults/service_accounts.yaml">
      ```yaml
      # yaml-language-server: $schema=https://platform.claude.com/schemas/ant/beta/vault.json
      display_name: Service accounts
      ```
    </File>

    [`ant apply`](https://platform.claude.com/docs/fr/cli-sdks-libraries/cli/apply) crée le coffre-fort à partir de `vaults/service_accounts.yaml`, affiche son ID et l'enregistre dans `claude-lock.json`. Pour consulter l'enregistrement du coffre-fort, exécutez `ant beta:vaults retrieve`.
  </CodeGroupItem>

  ```python Python
  vault = client.beta.vaults.create(
      display_name="Alice",
      metadata={"external_user_id": "usr_abc123"},
  )
  print(vault.id)  # "vlt_01ABC..."
  ```

  ```typescript TypeScript
  const vault = await client.beta.vaults.create({
    display_name: "Alice",
    metadata: { external_user_id: "usr_abc123" }
  });
  console.log(vault.id); // "vlt_01ABC..."
  ```

  ```csharp C#
  var vault = await client.Beta.Vaults.Create(new()
  {
      DisplayName = "Alice",
      Metadata = new Dictionary<string, string> { ["external_user_id"] = "usr_abc123" },
  });
  Console.WriteLine(vault.ID); // "vlt_01ABC..."
  ```

  ```go Go
  vault, err := client.Beta.Vaults.New(ctx, anthropic.BetaVaultNewParams{
  	DisplayName: "Alice",
  	Metadata:    map[string]string{"external_user_id": "usr_abc123"},
  })
  if err != nil {
  	panic(err)
  }
  fmt.Println(vault.ID) // "vlt_01ABC..."
  ```

  ```java Java
  var vault = client.beta().vaults().create(VaultCreateParams.builder()
      .displayName("Alice")
      .metadata(VaultCreateParams.Metadata.builder()
          .putAdditionalProperty("external_user_id", JsonValue.from("usr_abc123"))
          .build())
      .build());
  IO.println(vault.id()); // "vlt_01ABC..."
  ```

  ```php PHP
  $vault = $client->beta->vaults->create(
      displayName: 'Alice',
      metadata: ['external_user_id' => 'usr_abc123'],
  );
  echo $vault->id . "\n"; // "vlt_01ABC..."
  ```

  ```ruby Ruby
  vault = client.beta.vaults.create(
    display_name: "Alice",
    metadata: {external_user_id: "usr_abc123"}
  )
  puts vault.id # "vlt_01ABC..."
  ```
</CodeGroup>

La réponse est l'enregistrement complet du coffre-fort :

```json
{
  "type": "vault",
  "id": "vlt_01ABC...",
  "display_name": "Alice",
  "metadata": { "external_user_id": "usr_abc123" },
  "created_at": "2026-03-18T10:00:00Z",
  "updated_at": "2026-03-18T10:00:00Z",
  "archived_at": null
}
```

## Ajouter un identifiant

Deux catégories d'identifiants sont prises en charge :

* **Identifiants MCP** (`mcp_oauth`, `static_bearer`) : chaque identifiant est indexé par un `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`). Lorsque l'agent se connecte à un serveur à cette URL pendant l'exécution de la session, le jeton est injecté automatiquement.
* **Variables d'environnement** (`environment_variable`) : chaque identifiant est indexé par un `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (le nom de la variable d'environnement) et stocké dans le bac à sable sous la forme d'un placeholder opaque. Lorsque l'agent lance une requête sortante, le placeholder opaque est remplacé par le véritable secret en sortie (egress). L'agent ne voit jamais la valeur du secret. Utilisez cette option pour tout service qui s'authentifie via une variable d'environnement, comme les CLI, les SDK ou les appels API directs.

Les valeurs réelles des identifiants que vous fournissez (`token` (csharp, go: `Token`), `access_token` (java, php: `accessToken`; csharp, go: `AccessToken`), `refresh_token` (java, php: `refreshToken`; csharp, go: `RefreshToken`), `client_secret` (java, php: `clientSecret`; csharp, go: `ClientSecret`), `secret_value` (java, php: `secretValue`; csharp, go: `SecretValue`)) sont traitées comme des champs sensibles en écriture seule et ne sont jamais renvoyées dans les réponses de l'API.

<Note>
  Les identifiants de variables d'environnement (`environment_variable`) ne sont pas encore pris en charge avec les [bacs à sable auto-hébergés](https://platform.claude.com/docs/fr/managed-agents/self-hosted-sandboxes).
</Note>

Pour obtenir le même comportement avec un bac à sable auto-hébergé, vous pouvez exécuter votre propre proxy qui remplace les valeurs de placeholder par les véritables secrets en sortie.

<Tabs>
  <Tab title="MCP OAuth">
    Utilisez `mcp_oauth` lorsque le serveur MCP utilise OAuth 2.0. Si vous fournissez un bloc `refresh` (csharp, go: `Refresh`), Anthropic rafraîchit le jeton d'accès en votre nom lorsqu'il expire.

    Le champ `refresh.token_endpoint_auth.type` indique comment authentifier l'appel de rafraîchissement :

    * `none` : client public
    * `client_secret_basic` : authentification HTTP Basic avec le secret client
    * `client_secret_post` : secret client dans le corps POST

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "display_name": "Alice's Slack",
        "auth": {
          "type": "mcp_oauth",
          "mcp_server_url": "https://mcp.slack.com/mcp",
          "access_token": "xoxp-...",
          "expires_at": "2099-12-31T23:59:59Z",
          "refresh": {
            "token_endpoint": "https://slack.com/api/oauth.v2.user.access",
            "client_id": "1234567890.0987654321",
            "scope": "channels:read chat:write",
            "refresh_token": "xoxe-1-...",
            "token_endpoint_auth": {"type": "client_secret_post", "client_secret": "abc123..."}
          }
        }
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create \
        --vault-id "$VAULT_ID" \
        --display-name "Slack" <<'YAML'
      auth:
        type: mcp_oauth
        mcp_server_url: https://mcp.slack.com/mcp
        access_token: xoxp-...
        expires_at: "2099-12-31T23:59:59Z"
        refresh:
          token_endpoint: https://slack.com/api/oauth.v2.user.access
          client_id: "1234567890.0987654321"
          scope: channels:read chat:write
          refresh_token: xoxe-1-...
          token_endpoint_auth:
            type: client_secret_post
            client_secret: abc123...
      YAML
      ```

      ```python Python
      credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Alice's Slack",
          auth={
              "type": "mcp_oauth",
              "mcp_server_url": "https://mcp.slack.com/mcp",
              "access_token": "xoxp-...",
              "expires_at": "2099-12-31T23:59:59Z",
              "refresh": {
                  "token_endpoint": "https://slack.com/api/oauth.v2.user.access",
                  "client_id": "1234567890.0987654321",
                  "scope": "channels:read chat:write",
                  "refresh_token": "xoxe-1-...",
                  "token_endpoint_auth": {
                      "type": "client_secret_post",
                      "client_secret": "abc123...",
                  },
              },
          },
      )
      ```

      ```typescript TypeScript
      const credential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Alice's Slack",
        auth: {
          type: "mcp_oauth",
          mcp_server_url: "https://mcp.slack.com/mcp",
          access_token: "xoxp-...",
          expires_at: "2099-12-31T23:59:59Z",
          refresh: {
            token_endpoint: "https://slack.com/api/oauth.v2.user.access",
            client_id: "1234567890.0987654321",
            scope: "channels:read chat:write",
            refresh_token: "xoxe-1-...",
            token_endpoint_auth: {
              type: "client_secret_post",
              client_secret: "abc123..."
            }
          }
        }
      });
      ```

      ```csharp C#
      var credential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Alice's Slack",
          Auth = new BetaManagedAgentsMcpOAuthCreateParams
          {
              Type = BetaManagedAgentsMcpOAuthCreateParamsType.McpOAuth,
              McpServerUrl = "https://mcp.slack.com/mcp",
              AccessToken = "xoxp-...",
              ExpiresAt = DateTimeOffset.Parse("2099-12-31T23:59:59Z"),
              Refresh = new()
              {
                  TokenEndpoint = "https://slack.com/api/oauth.v2.user.access",
                  ClientID = "1234567890.0987654321",
                  Scope = "channels:read chat:write",
                  RefreshToken = "xoxe-1-...",
                  TokenEndpointAuth = new BetaManagedAgentsTokenEndpointAuthPostParam
                  {
                      Type = BetaManagedAgentsTokenEndpointAuthPostParamType.ClientSecretPost,
                      ClientSecret = "abc123...",
                  },
              },
          },
      });
      ```

      ```go Go
      credential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Alice's Slack"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfMCPOAuth: &anthropic.BetaManagedAgentsMCPOAuthCreateParams{
      			Type:         anthropic.BetaManagedAgentsMCPOAuthCreateParamsTypeMCPOAuth,
      			MCPServerURL: "https://mcp.slack.com/mcp",
      			AccessToken:  "xoxp-...",
      			ExpiresAt:    anthropic.Time(time.Date(2099, time.December, 31, 23, 59, 59, 0, time.UTC)),
      			Refresh: anthropic.BetaManagedAgentsMCPOAuthRefreshParams{
      				TokenEndpoint: "https://slack.com/api/oauth.v2.user.access",
      				ClientID:      "1234567890.0987654321",
      				Scope:         anthropic.String("channels:read chat:write"),
      				RefreshToken:  "xoxe-1-...",
      				TokenEndpointAuth: anthropic.BetaManagedAgentsMCPOAuthRefreshParamsTokenEndpointAuthUnion{
      					OfClientSecretPost: &anthropic.BetaManagedAgentsTokenEndpointAuthPostParam{
      						Type:         anthropic.BetaManagedAgentsTokenEndpointAuthPostParamTypeClientSecretPost,
      						ClientSecret: "abc123...",
      					},
      				},
      			},
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      ```

      ```java Java
      var credential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Alice's Slack")
              .auth(BetaManagedAgentsMcpOAuthCreateParams.builder()
                  .type(BetaManagedAgentsMcpOAuthCreateParams.Type.MCP_OAUTH)
                  .mcpServerUrl("https://mcp.slack.com/mcp")
                  .accessToken("xoxp-...")
                  .expiresAt(OffsetDateTime.parse("2099-12-31T23:59:59Z"))
                  .refresh(BetaManagedAgentsMcpOAuthRefreshParams.builder()
                      .tokenEndpoint("https://slack.com/api/oauth.v2.user.access")
                      .clientId("1234567890.0987654321")
                      .scope("channels:read chat:write")
                      .refreshToken("xoxe-1-...")
                      .clientSecretPostTokenEndpointAuth("abc123...")
                      .build())
                  .build())
              .build());
      ```

      ```php PHP
      $credential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: "Alice's Slack",
          auth: ManagedAgentsMCPOAuthCreateParams::with(
              type: 'mcp_oauth',
              mcpServerURL: 'https://mcp.slack.com/mcp',
              accessToken: 'xoxp-...',
              expiresAt: new \DateTimeImmutable('2099-12-31T23:59:59Z'),
              refresh: ManagedAgentsMCPOAuthRefreshParams::with(
                  tokenEndpoint: 'https://slack.com/api/oauth.v2.user.access',
                  clientID: '1234567890.0987654321',
                  scope: 'channels:read chat:write',
                  refreshToken: 'xoxe-1-...',
                  tokenEndpointAuth: ManagedAgentsTokenEndpointAuthPostParam::with(
                      type: 'client_secret_post',
                      clientSecret: 'abc123...',
                  ),
              ),
          ),
      );
      ```

      ```ruby Ruby
      credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Alice's Slack",
        auth: {
          type: "mcp_oauth",
          mcp_server_url: "https://mcp.slack.com/mcp",
          access_token: "xoxp-...",
          expires_at: "2099-12-31T23:59:59Z",
          refresh: {
            token_endpoint: "https://slack.com/api/oauth.v2.user.access",
            client_id: "1234567890.0987654321",
            scope: "channels:read chat:write",
            refresh_token: "xoxe-1-...",
            token_endpoint_auth: {
              type: "client_secret_post",
              client_secret: "abc123..."
            }
          }
        }
      )
      ```
    </CodeGroup>

    Définissez `refresh.token_endpoint` (java, php: `refresh.tokenEndpoint`; csharp, go: `Refresh.TokenEndpoint`) sur le point de terminaison de jeton du flux OAuth qui a émis le jeton de rafraîchissement, car Anthropic envoie chaque requête de rafraîchissement à cette URL et ce champ ne peut pas être modifié après la création de l'identifiant.
  </Tab>

  <Tab title="MCP static bearer">
    Utilisez `static_bearer` lorsque le serveur MCP accepte un jeton bearer fixe (clé API, jeton d'accès personnel ou similaire). Aucun flux de rafraîchissement n'est nécessaire.

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "display_name": "Linear API key",
        "auth": {
          "type": "static_bearer",
          "mcp_server_url": "https://mcp.linear.app/mcp",
          "token": "lin_api_your_linear_key"
        }
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create --vault-id "$VAULT_ID" <<'YAML'
      display_name: Linear API key
      auth:
        type: static_bearer
        mcp_server_url: https://mcp.linear.app/mcp
        token: lin_api_your_linear_key
      YAML
      ```

      ```python Python
      bearer_credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Linear API key",
          auth={
              "type": "static_bearer",
              "mcp_server_url": "https://mcp.linear.app/mcp",
              "token": "lin_api_your_linear_key",
          },
      )
      ```

      ```typescript TypeScript
      const bearerCredential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Linear API key",
        auth: {
          type: "static_bearer",
          mcp_server_url: "https://mcp.linear.app/mcp",
          token: "lin_api_your_linear_key"
        }
      });
      ```

      ```csharp C#
      var bearerCredential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Linear API key",
          Auth = new BetaManagedAgentsStaticBearerCreateParams
          {
              Type = BetaManagedAgentsStaticBearerCreateParamsType.StaticBearer,
              McpServerUrl = "https://mcp.linear.app/mcp",
              Token = "lin_api_your_linear_key",
          },
      });
      ```

      ```go Go
      bearerCredential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Linear API key"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfStaticBearer: &anthropic.BetaManagedAgentsStaticBearerCreateParams{
      			Type:         anthropic.BetaManagedAgentsStaticBearerCreateParamsTypeStaticBearer,
      			MCPServerURL: "https://mcp.linear.app/mcp",
      			Token:        "lin_api_your_linear_key",
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      _ = bearerCredential
      ```

      ```java Java
      var bearerCredential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Linear API key")
              .auth(BetaManagedAgentsStaticBearerCreateParams.builder()
                  .type(BetaManagedAgentsStaticBearerCreateParams.Type.STATIC_BEARER)
                  .mcpServerUrl("https://mcp.linear.app/mcp")
                  .token("lin_api_your_linear_key")
                  .build())
              .build());
      ```

      ```php PHP
      $bearerCredential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: 'Linear API key',
          auth: ManagedAgentsStaticBearerCreateParams::with(
              type: 'static_bearer',
              mcpServerURL: 'https://mcp.linear.app/mcp',
              token: 'lin_api_your_linear_key',
          ),
      );
      ```

      ```ruby Ruby
      bearer_credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Linear API key",
        auth: {
          type: "static_bearer",
          mcp_server_url: "https://mcp.linear.app/mcp",
          token: "lin_api_your_linear_key"
        }
      )
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Environment variable">
    Utilisez `environment_variable` pour vous authentifier auprès de services externes via une variable d'environnement, comme les CLI, les SDK ou les appels API directs. Les identifiants de variables d'environnement fonctionnent pour les clients qui envoient la valeur du secret telle quelle dans une requête sortante, alors vérifiez les critères d'éligibilité du client dans cet onglet avant d'en configurer un.

    Le tableau `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) dans `networking` (csharp, go: `Networking`) contrôle les hôtes sortants pour lesquels le secret peut être substitué. Utilisez `"type": "limited"` avec une liste spécifique, ou `"type": "unrestricted"` si l'appelant accède à des domaines que vous ne pouvez pas énumérer à l'avance.

    Limiter les domaines est fortement recommandé à des fins de sécurité, et empêche votre clé d'être jamais partagée avec des hôtes non autorisés.

    <Note>
      `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) dans `networking` (csharp, go: `Networking`) sur un identifiant de coffre-fort contrôle quelles requêtes utilisent le secret, et non quelles requêtes sont autorisées. Pour que l'agent puisse réellement atteindre un domaine, celui-ci doit également être autorisé au [niveau de l'environnement](https://platform.claude.com/docs/fr/managed-agents/environments). Les deux niveaux doivent inclure le domaine (soit via une mise en réseau `unrestricted`, soit en listant explicitement le domaine dans `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)) pour qu'une requête avec substitution de secret réussisse.
    </Note>

    Le champ facultatif `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) délimite l'endroit où le secret est substitué ; la sémantique complète est décrite après l'exemple.

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "auth": {
          "type": "environment_variable",
          "secret_name": "NOTION_API_KEY",
          "secret_value": "ntn_your-secret-here",
          "networking": {
            "type": "limited",
            "allowed_hosts": ["api.notion.com"]
          },
          "injection_location": {"header": true}
        },
        "display_name": "Notion API key for sandbox"
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create --vault-id "$VAULT_ID" <<'YAML'
      display_name: Notion API key for sandbox
      auth:
        type: environment_variable
        secret_name: NOTION_API_KEY
        secret_value: ntn_your-secret-here
        injection_location:
          header: true
        networking:
          type: limited
          allowed_hosts: [api.notion.com]
      YAML
      ```

      ```python Python
      env_credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Notion API key for sandbox",
          auth={
              "type": "environment_variable",
              "secret_name": "NOTION_API_KEY",
              "secret_value": "ntn_your-secret-here",
              "networking": {
                  "type": "limited",
                  "allowed_hosts": ["api.notion.com"],
              },
              "injection_location": {"header": True},
          },
      )
      if env_credential.auth.type == "environment_variable":
          location = env_credential.auth.injection_location
          print(
              f"header: {location.header}, body: {location.body}"
          )  # header: True, body: False
      ```

      ```typescript TypeScript
      const envVarCredential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Notion API key for sandbox",
        auth: {
          type: "environment_variable",
          secret_name: "NOTION_API_KEY",
          secret_value: "ntn_your-secret-here",
          networking: {
            type: "limited",
            allowed_hosts: ["api.notion.com"]
          },
          injection_location: { header: true }
        }
      });
      if (envVarCredential.auth.type === "environment_variable") {
        console.log(envVarCredential.auth.injection_location); // { header: true, body: false }
      }
      ```

      ```csharp C#
      var envVarCredential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Notion API key for sandbox",
          Auth = new BetaManagedAgentsEnvironmentVariableCreateParams
          {
              Type = BetaManagedAgentsEnvironmentVariableCreateParamsType.EnvironmentVariable,
              SecretName = "NOTION_API_KEY",
              SecretValue = "ntn_your-secret-here",
              Networking = new BetaManagedAgentsLimitedCredentialNetworkingParams
              {
                  Type = BetaManagedAgentsLimitedCredentialNetworkingParamsType.Limited,
                  AllowedHosts = ["api.notion.com"],
              },
              InjectionLocation = new() { Header = true },
          },
      });
      if (envVarCredential.Auth.TryPickBetaManagedAgentsEnvironmentVariableAuthResponse(out var envVarAuth))
      {
          var injectionLocation = envVarAuth.InjectionLocation;
          Console.WriteLine($"Header: {injectionLocation.Header}, Body: {injectionLocation.Body}"); // "Header: True, Body: False"
      }
      ```

      ```go Go
      envVarCredential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Notion API key for sandbox"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfEnvironmentVariable: &anthropic.BetaManagedAgentsEnvironmentVariableCreateParams{
      			Type:        anthropic.BetaManagedAgentsEnvironmentVariableCreateParamsTypeEnvironmentVariable,
      			SecretName:  "NOTION_API_KEY",
      			SecretValue: "ntn_your-secret-here",
      			Networking: anthropic.BetaManagedAgentsCredentialNetworkingParamsUnion{
      				OfLimited: &anthropic.BetaManagedAgentsLimitedCredentialNetworkingParams{
      					Type:         anthropic.BetaManagedAgentsLimitedCredentialNetworkingParamsTypeLimited,
      					AllowedHosts: []string{"api.notion.com"},
      				},
      			},
      			InjectionLocation: anthropic.BetaManagedAgentsInjectionLocationParams{
      				Header: anthropic.Bool(true),
      			},
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      if envVarAuth, ok := envVarCredential.Auth.AsAny().(anthropic.BetaManagedAgentsEnvironmentVariableAuthResponse); ok {
      	injectionLocation := envVarAuth.InjectionLocation
      	fmt.Printf("Header:%t Body:%t\n", injectionLocation.Header, injectionLocation.Body) // "Header:true Body:false"
      }
      ```

      ```java Java
      var envVarCredential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Notion API key for sandbox")
              .auth(BetaManagedAgentsEnvironmentVariableCreateParams.builder()
                  .type(BetaManagedAgentsEnvironmentVariableCreateParams.Type.ENVIRONMENT_VARIABLE)
                  .secretName("NOTION_API_KEY")
                  .secretValue("ntn_your-secret-here")
                  .limitedNetworking(List.of("api.notion.com"))
                  .injectionLocation(BetaManagedAgentsInjectionLocationParams.builder()
                      .header(true)
                      .build())
                  .build())
              .build());
      envVarCredential.auth().environmentVariable().ifPresent(envVarAuth -> {
          var injectionLocation = envVarAuth.injectionLocation();
          IO.println("header=" + injectionLocation.header() + " body=" + injectionLocation.body()); // header=true body=false
      });
      ```

      ```php PHP
      $envVarCredential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: 'Notion API key for sandbox',
          auth: ManagedAgentsEnvironmentVariableCreateParams::with(
              type: ManagedAgentsEnvironmentVariableCreateParams\Type::ENVIRONMENT_VARIABLE,
              secretName: 'NOTION_API_KEY',
              secretValue: 'ntn_your-secret-here',
              networking: ManagedAgentsLimitedCredentialNetworkingParams::with(
                  type: ManagedAgentsLimitedCredentialNetworkingParams\Type::LIMITED,
                  allowedHosts: ['api.notion.com'],
              ),
              injectionLocation: ManagedAgentsInjectionLocationParams::with(header: true),
          ),
      );
      if ($envVarCredential->auth instanceof \Anthropic\Beta\Vaults\Credentials\ManagedAgentsEnvironmentVariableAuthResponse) {
          $injectionLocation = $envVarCredential->auth->injectionLocation;
          echo 'header: ' . json_encode($injectionLocation->header) . "\n"; // header: true
          echo 'body: ' . json_encode($injectionLocation->body) . "\n"; // body: false
      }
      ```

      ```ruby Ruby
      env_credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Notion API key for sandbox",
        auth: {
          type: "environment_variable",
          secret_name: "NOTION_API_KEY",
          secret_value: "ntn_your-secret-here",
          networking: {
            type: "limited",
            allowed_hosts: ["api.notion.com"]
          },
          injection_location: {header: true}
        }
      )
      if env_credential.auth.type == :environment_variable
        env_credential.auth.injection_location => {header:, body:}
        puts "header: #{header}, body: #{body}" # header: true, body: false
      end
      ```
    </CodeGroup>

    Les charges utiles des requêtes sont souvent assemblées à partir du contenu sur lequel l'agent travaille ; le corps de la requête constitue donc la surface d'exposition la plus large. La plupart des services lisent une clé API depuis un en-tête de requête ; activer uniquement `header` (csharp, go: `Header`) est donc la configuration la plus restreinte. Elle limite la substitution aux valeurs des en-têtes de requête pour cet identifiant.

    Le champ `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) de l'identifiant contrôle les parties d'une requête sortante dans lesquelles le secret est substitué. Il s'agit d'un objet facultatif, au même niveau que `networking` (csharp, go: `Networking`), avec deux champs booléens : `header` (csharp, go: `Header`) (en-têtes de requête) et `body` (csharp, go: `Body`) (corps de la requête). `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) est indépendant de `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) dans `networking` (csharp, go: `Networking`) : `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) délimite les hôtes pour lesquels le secret est substitué, et `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) délimite les parties de la requête dans lesquelles il est substitué.

    `injection_location` se comporte différemment lors de la création et lors de la mise à jour :

    | Opération                    | Comportement de `injection_location`                                                                                                                                                                                                            |
    | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Créer un identifiant         | Si vous fournissez l'objet, tout champ que vous omettez à l'intérieur prend par défaut la valeur `false` : `{"header": true}` crée un identifiant uniquement pour l'en-tête. Omettez entièrement l'objet et les deux emplacements sont activés. |
    | Mettre à jour un identifiant | Les champs fusionnent individuellement : `{"body": false}` désactive la substitution dans le corps et laisse `header` inchangé.                                                                                                                 |

    Un identifiant doit avoir au moins un emplacement activé ; une création ou une mise à jour qui désactiverait les deux emplacements renvoie donc une erreur 400. Transmettre un `null` explicite pour l'objet `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) ou pour l'un de ses champs renvoie également une erreur 400 (« omit the field instead »). La réponse renvoie toujours les deux champs avec leurs valeurs résolues.

    Un placeholder situé dans un emplacement désactivé n'est ni substitué ni supprimé. La requête est envoyée au tiers avec la chaîne de placeholder opaque littérale à cet emplacement. Si une requête parvient au tiers en contenant la chaîne de placeholder littérale, soit cet emplacement est désactivé pour l'identifiant, soit l'hôte de destination n'est pas couvert par les `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) dans le `networking` (csharp, go: `Networking`) de l'identifiant.

    <Note>
      Les identifiants créés dans la Console n'activent que l'injection dans l'en-tête. Si votre client envoie le secret dans le corps de la requête, comme une requête de jeton encodée en formulaire, le placeholder passe littéralement et le service le rejette avec sa propre erreur d'authentification. Activez l'injection dans le corps dans le formulaire de la Console lorsque vous créez l'identifiant, ou mettez à jour l'identifiant avec `{"injection_location": {"body": true}}`.
    </Note>

    La substitution a lieu en sortie, et non à l'intérieur du bac à sable. Tout ce qui traite l'identifiant localement voit le placeholder opaque, et non la valeur réelle : les clients qui valident le format de l'identifiant au démarrage peuvent le rejeter, et les clients qui calculent une signature de requête à partir du secret (par exemple, AWS SigV4) produisent une signature invalide. Les identifiants de variables d'environnement fonctionnent pour les clients qui envoient la valeur du secret telle quelle dans une requête sortante, à un emplacement activé par le champ `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) de l'identifiant.

    La substitution est uniquement sortante. Si un client utilise le secret stocké pour récupérer un jeton de session (par exemple, une autorisation OAuth client-credentials), le jeton renvoyé arrive dans le bac à sable non masqué. Pour les flux basés sur l'échange, effectuez l'échange vous-même et stockez plutôt le jeton résultant dans le coffre-fort.

    <Tip>
      Limitez la clé API aux seules permissions dont l'agent a besoin. L'agent peut faire tout ce que la clé autorise, donc une clé avec des permissions plus larges que nécessaire augmente le rayon d'impact si l'agent se comporte de manière inattendue.
    </Tip>
  </Tab>
</Tabs>

Les identifiants sont stockés tels que fournis et ne sont pas validés avant l'exécution de la session. Un identifiant invalide se manifeste comme une erreur d'authentification ou une erreur en aval pendant la session, qui est émise mais n'empêche pas la session de continuer.

Contraintes :

* **Clé unique par coffre-fort.** `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) (identifiants MCP) et `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (identifiants de variables d'environnement) doivent être uniques parmi les identifiants actifs d'un coffre-fort. La création d'un doublon renvoie une erreur 409.
* **Les clés sont immuables.** Pour modifier `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) ou `secret_name` (java, php: `secretName`; csharp, go: `SecretName`), archivez l'identifiant et créez-en un nouveau.
* **Maximum de 20 identifiants par coffre-fort.**

## Référencer le coffre-fort lors de la création de la session

Transmettez `vault_ids` (java: `vaultIds`; php: `vaultIDs`; csharp: `VaultIds`; go: `VaultIDs`) lors de la création d'une session :

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/sessions \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    --data '{
      "agent": "'"$AGENT_ID"'",
      "environment_id": "'"$ENVIRONMENT_ID"'",
      "vault_ids": ["'"$VAULT_ID"'"],
      "title": "Slack digest for Alice"
    }'
  ```

  ```bash CLI
  ant beta:sessions create \
    --agent "$AGENT_ID" \
    --environment-id "$ENVIRONMENT_ID" \
    --vault-id "$VAULT_ID" \
    --title "Slack digest"
  ```

  ```python Python
  session = client.beta.sessions.create(
      agent=agent.id,
      environment_id=environment.id,
      vault_ids=[vault.id],
      title="Alice's Slack digest",
  )
  ```

  ```typescript TypeScript
  const session = await client.beta.sessions.create({
    agent: agent.id,
    environment_id: environment.id,
    vault_ids: [vault.id],
    title: "Alice's Slack digest"
  });
  ```

  ```csharp C#
  var session = await client.Beta.Sessions.Create(new()
  {
      Agent = agent.ID,
      EnvironmentID = environment.ID,
      VaultIds = [vault.ID],
      Title = "Alice's Slack digest",
  });
  ```

  ```go Go
  session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
  	Agent: anthropic.BetaSessionNewParamsAgentUnion{
  		OfString: anthropic.String(agent.ID),
  	},
  	EnvironmentID: environment.ID,
  	VaultIDs:      []string{vault.ID},
  	Title:         anthropic.String("Alice's Slack digest"),
  })
  if err != nil {
  	panic(err)
  }
  ```

  ```java Java
  var session = client.beta().sessions().create(SessionCreateParams.builder()
      .agent(agent.id())
      .environmentId(environment.id())
      .vaultIds(List.of(vault.id()))
      .title("Alice's Slack digest")
      .build());
  ```

  ```php PHP
  $session = $client->beta->sessions->create(
      agent: $agent->id,
      environmentID: $environment->id,
      vaultIDs: [$vault->id],
      title: "Alice's Slack digest",
  );
  ```

  ```ruby Ruby
  session = client.beta.sessions.create(
    agent: agent.id,
    environment_id: environment.id,
    vault_ids: [vault.id],
    title: "Alice's Slack digest"
  )
  ```
</CodeGroup>

Comportement à l'exécution :

* Lorsqu'aucun identifiant MCP ne correspond par `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`), la connexion est tentée sans authentification et échouera si le serveur exige une authentification.
* Lorsque plusieurs coffres-forts contiennent un identifiant correspondant, le premier coffre-fort avec une correspondance l'emporte.
* Dans les [sessions multiagents](https://platform.claude.com/docs/fr/managed-agents/multiagent-orchestration), les identifiants du coffre-fort s'appliquent à chaque thread. Un agent dont la propre définition déclare le serveur MCP correspondant s'authentifie avec ces identifiants. Consultez [Connecter des agents à des serveurs MCP](https://platform.claude.com/docs/fr/managed-agents/multiagent-orchestration#connect-agents-to-mcp-servers).

## Faire tourner un identifiant

Les valeurs secrètes, `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) et (pour les identifiants de variables d'environnement) `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) peuvent être mis à jour. Les mises à jour de `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) sont fusionnées champ par champ, comme décrit dans l'onglet Variable d'environnement de [Ajouter un identifiant](https://platform.claude.com/docs/fr/managed-agents/vaults#add-a-credential). Pour une session en cours d'exécution, une mise à jour de `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) se propage de la même manière qu'une rotation de secret : les identifiants de la session sont re-résolus sans redémarrage, comme décrit dans [Cycle de vie des identifiants](https://platform.claude.com/docs/fr/managed-agents/vaults#credential-lifecycle), et les emplacements mis à jour s'appliquent aux requêtes sortantes ultérieures de la session. Les champs structurels (`mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`), `secret_name` (java, php: `secretName`; csharp, go: `SecretName`), `token_endpoint` (java, php: `tokenEndpoint`; csharp, go: `TokenEndpoint`), `client_id` (java: `clientId`; php: `clientID`; csharp, go: `ClientID`)) sont verrouillés après la création. Pour les modifier, archivez l'identifiant et créez-en un nouveau.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS \
    "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials/$CREDENTIAL_ID" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d @- <<'EOF'
  {
    "auth": {
      "type": "mcp_oauth",
      "access_token": "xoxp-new-...",
      "expires_at": "2099-12-31T23:59:59Z",
      "refresh": {"refresh_token": "xoxe-1-new-..."}
    }
  }
  EOF
  ```

  ```bash CLI
  ant beta:vaults:credentials update \
    --vault-id "$VAULT_ID" \
    --credential-id "$CREDENTIAL_ID" <<'YAML'
  auth:
    type: mcp_oauth
    access_token: xoxp-new-...
    expires_at: "2099-12-31T23:59:59Z"
    refresh:
      refresh_token: xoxe-1-new-...
  YAML
  ```

  ```python Python
  client.beta.vaults.credentials.update(
      credential.id,
      vault_id=vault.id,
      auth={
          "type": "mcp_oauth",
          "access_token": "xoxp-new-...",
          "expires_at": "2099-12-31T23:59:59Z",
          "refresh": {"refresh_token": "xoxe-1-new-..."},
      },
  )
  ```

  ```typescript TypeScript
  await client.beta.vaults.credentials.update(credential.id, {
    vault_id: vault.id,
    auth: {
      type: "mcp_oauth",
      access_token: "xoxp-new-...",
      expires_at: "2099-12-31T23:59:59Z",
      refresh: {
        refresh_token: "xoxe-1-new-..."
      }
    }
  });
  ```

  ```csharp C#
  await client.Beta.Vaults.Credentials.Update(credential.ID, new()
  {
      VaultID = vault.ID,
      Auth = new BetaManagedAgentsMcpOAuthUpdateParams
      {
          Type = BetaManagedAgentsMcpOAuthUpdateParamsType.McpOAuth,
          AccessToken = "xoxp-new-...",
          ExpiresAt = DateTimeOffset.Parse("2099-12-31T23:59:59Z"),
          Refresh = new() { RefreshToken = "xoxe-1-new-..." },
      },
  });
  ```

  ```go Go
  _, err = client.Beta.Vaults.Credentials.Update(ctx, credential.ID, anthropic.BetaVaultCredentialUpdateParams{
  	VaultID: vault.ID,
  	Auth: anthropic.BetaVaultCredentialUpdateParamsAuthUnion{
  		OfMCPOAuth: &anthropic.BetaManagedAgentsMCPOAuthUpdateParams{
  			Type:        anthropic.BetaManagedAgentsMCPOAuthUpdateParamsTypeMCPOAuth,
  			AccessToken: anthropic.String("xoxp-new-..."),
  			ExpiresAt:   anthropic.Time(time.Date(2099, time.December, 31, 23, 59, 59, 0, time.UTC)),
  			Refresh: anthropic.BetaManagedAgentsMCPOAuthRefreshUpdateParams{
  				RefreshToken: anthropic.String("xoxe-1-new-..."),
  			},
  		},
  	},
  })
  if err != nil {
  	panic(err)
  }
  ```

  ```java Java
  client.beta().vaults().credentials().update(credential.id(),
      CredentialUpdateParams.builder()
          .vaultId(vault.id())
          .auth(BetaManagedAgentsMcpOAuthUpdateParams.builder()
              .type(BetaManagedAgentsMcpOAuthUpdateParams.Type.MCP_OAUTH)
              .accessToken("xoxp-new-...")
              .expiresAt(OffsetDateTime.parse("2099-12-31T23:59:59Z"))
              .refresh(BetaManagedAgentsMcpOAuthRefreshUpdateParams.builder()
                  .refreshToken("xoxe-1-new-...")
                  .build())
              .build())
          .build());
  ```

  ```php PHP
  $client->beta->vaults->credentials->update(
      $credential->id,
      vaultID: $vault->id,
      auth: ManagedAgentsMCPOAuthUpdateParams::with(
          type: 'mcp_oauth',
          accessToken: 'xoxp-new-...',
          expiresAt: new \DateTimeImmutable('2099-12-31T23:59:59Z'),
          refresh: ManagedAgentsMCPOAuthRefreshUpdateParams::with(refreshToken: 'xoxe-1-new-...'),
      ),
  );
  ```

  ```ruby Ruby
  client.beta.vaults.credentials.update(
    credential.id,
    vault_id: vault.id,
    auth: {
      type: "mcp_oauth",
      access_token: "xoxp-new-...",
      expires_at: "2099-12-31T23:59:59Z",
      refresh: {refresh_token: "xoxe-1-new-..."}
    }
  )
  ```
</CodeGroup>

## Cycle de vie des identifiants

Les identifiants sont re-résolus périodiquement, à la fois pendant une session et pendant le cycle de vie du coffre-fort. Cela garantit que la rotation, l'archivage ou la suppression d'un identifiant se propage aux sessions en cours sans redémarrage.

Pour être notifié si un identifiant est archivé, supprimé ou échoue à se rafraîchir, vous pouvez vous abonner aux [webhooks](https://platform.claude.com/docs/fr/managed-agents/webhooks) de coffre-fort et d'identifiant associés à ces changements de cycle de vie.

| Événement                         | Déclencheur                                                                                                                           |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `vault.archived`                  | Coffre-fort archivé. Un événement `vault_credential.archived` est également émis pour chaque identifiant sous-jacent.                 |
| `vault.deleted`                   | Coffre-fort supprimé. Un événement `vault_credential.deleted` est également émis pour chaque identifiant sous-jacent.                 |
| `vault_credential.archived`       | Identifiant archivé, soit directement, soit à la suite de l'archivage du coffre-fort.                                                 |
| `vault_credential.deleted`        | Identifiant supprimé, soit directement, soit à la suite de la suppression du coffre-fort.                                             |
| `vault_credential.refresh_failed` | Un identifiant `mcp_oauth` ne peut pas être rafraîchi (jeton de rafraîchissement invalide, ou erreur irrécupérable du serveur OAuth). |

<Note>
  Ceci est une liste non exhaustive de webhooks ; consultez [S'abonner aux webhooks](https://platform.claude.com/docs/fr/managed-agents/webhooks) pour la liste complète.
</Note>

Pour les identifiants `mcp_oauth`, la re-résolution rafraîchit également le jeton d'accès s'il a expiré. Si le rafraîchissement échoue, un événement `vault_credential.refresh_failed` est émis.

### Diagnostiquer un échec de rafraîchissement OAuth

Pour diagnostiquer la cause d'un échec de rafraîchissement, appelez `POST /v1/vaults/{vault_id}/credentials/{credential_id}/mcp_oauth_validate` (ou `client.beta.vaults.credentials.mcp_oauth_validate(...)` (typescript: `client.beta.vaults.credentials.mcpOAuthValidate(...)`; csharp: `client.Beta.Vaults.Credentials.McpOAuthValidate(...)`; go: `client.Beta.Vaults.Credentials.MCPOAuthValidate(...)`; java: `client.beta().vaults().credentials().mcpOAuthValidate(...)`; php: `$client->beta->vaults->credentials->mcpOAuthValidate(...)`) dans le SDK). Vous pouvez ainsi décider comment traiter l'échec, car l'action appropriée dépend du type d'erreur.

Le champ `status` (csharp, go: `Status`) de premier niveau vous indique la marche à suivre :

* `valid` : le jeton fonctionne ; aucune action nécessaire.
* `invalid` : l'autorisation a disparu ou le serveur OAuth a rejeté le rafraîchissement avec une erreur 4xx. Invitez l'utilisateur final à se réautoriser.
* `unknown` : une erreur transitoire (5xx, 429, ou échec réseau). Attendez et réessayez.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS -X POST \
    "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials/$CREDENTIAL_ID/mcp_oauth_validate?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01"
  ```

  ```bash CLI
  ant beta:vaults:credentials mcp-oauth-validate \
    --vault-id "$VAULT_ID" \
    --credential-id "$CREDENTIAL_ID"
  ```

  ```python Python
  validation = client.beta.vaults.credentials.mcp_oauth_validate(
      credential.id,
      vault_id=vault.id,
  )
  print(validation.status)  # "valid", "invalid", or "unknown"
  ```

  ```typescript TypeScript
  const validation = await client.beta.vaults.credentials.mcpOAuthValidate(credential.id, {
    vault_id: vault.id
  });
  console.log(validation.status); // "valid", "invalid", or "unknown"
  ```

  ```csharp C#
  var validation = await client.Beta.Vaults.Credentials.McpOAuthValidate(credential.ID, new()
  {
      VaultID = vault.ID,
  });
  Console.WriteLine(validation.Status.Raw()); // "valid", "invalid", or "unknown"
  ```

  ```go Go
  validation, err := client.Beta.Vaults.Credentials.MCPOAuthValidate(ctx, credential.ID, anthropic.BetaVaultCredentialMCPOAuthValidateParams{
  	VaultID: vault.ID,
  })
  if err != nil {
  	panic(err)
  }
  fmt.Println(validation.Status) // "valid", "invalid", or "unknown"
  ```

  ```java Java
  var validation = client.beta().vaults().credentials().mcpOAuthValidate(credential.id(),
      CredentialMcpOAuthValidateParams.builder()
          .vaultId(vault.id())
          .build());
  IO.println(validation.status()); // valid, invalid, or unknown
  ```

  ```php PHP
  $validation = $client->beta->vaults->credentials->mcpOAuthValidate(
      $credential->id,
      vaultID: $vault->id,
  );
  echo $validation->status . "\n"; // "valid", "invalid", or "unknown"
  ```

  ```ruby Ruby
  validation = client.beta.vaults.credentials.mcp_oauth_validate(
    credential.id,
    vault_id: vault.id
  )
  puts validation.status # :valid, :invalid, or :unknown
  ```
</CodeGroup>

La réponse est un objet `vault_credential_validation`. `mcp_probe` inclut l'étape de handshake MCP ayant échoué ; `refresh` inclut le résultat du rafraîchissement tenté.

```json
{
  "type": "vault_credential_validation",
  "credential_id": "vcrd_01ABC...",
  "vault_id": "vlt_01XYZ...",
  "validated_at": "2026-04-29T17:12:00Z",
  "has_refresh_token": false,
  "status": "invalid",
  "mcp_probe": {
    "method": "initialize",
    "http_response": {
      "status_code": 401,
      "content_type": "application/json",
      "body": "{\"error\":\"invalid_token\"}",
      "body_truncated": false
    }
  },
  "refresh": {
    "status": "no_refresh_token",
    "http_response": null
  }
}
```

## Autres opérations

* **Lister les coffres-forts ou les identifiants :** Paginé, du plus récent au plus ancien. Les enregistrements archivés sont exclus par défaut (passez `include_archived=true` pour les inclure).
* **Archiver un coffre-fort :** `POST /v1/vaults/{id}/archive`. Se répercute sur tous les identifiants. Les secrets sont purgés ; les enregistrements sont conservés à des fins d'audit. Les futures sessions référençant ce coffre-fort échouent ; les sessions en cours continuent.
* **Archiver un identifiant :** `POST /v1/vaults/{id}/credentials/{cred_id}/archive`. Purge la charge utile du secret ; la clé de l'identifiant (`mcp_server_url` ou `secret_name`) reste visible et est libérée pour un identifiant de remplacement.
* **Supprimer un coffre-fort ou un identifiant :** Suppression définitive. L'enregistrement n'est pas conservé. Utilisez l'archivage si vous avez besoin d'une piste d'audit.
