---
title: Аутентификация с помощью хранилищ
url: https://platform.claude.com/docs/ru/managed-agents/vaults
description: Регистрируйте учётные данные для каждого пользователя при создании сессий.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

«Vaults» (хранилища) и «credentials» (учётные данные) — это примитивы аутентификации, которые позволяют вам один раз зарегистрировать учётные данные для сторонних сервисов и ссылаться на них по идентификатору при создании сессии. Это означает, что вам не нужно поддерживать собственное хранилище секретов, передавать токены при каждом вызове или терять информацию о том, от имени какого конечного пользователя действовал агент.

Ссылка на хранилище — это параметр уровня сессии, поэтому вы можете управлять своим продуктом на уровне ресурса `agent`, а своими пользователями — на уровне ресурса `session`.

## Создание хранилища

<Warning>
  Хранилища и учётные данные привязаны к рабочему пространству, то есть любой ключ API с доступом к рабочему пространству может ссылаться на них при создании сессии. Чтобы отозвать доступ, удалите хранилище или учётные данные.
</Warning>

Хранилище — это набор `credentials`, связанных с конечным пользователем. Задайте ему `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) и при необходимости пометьте его с помощью `metadata` (csharp, go: `Metadata`), чтобы сопоставить его с записями пользователей в вашей системе.

<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/ru/cli-sdks-libraries/cli/apply) создаёт хранилище из `vaults/service_accounts.yaml`, выводит его ID и записывает его в `claude-lock.json`. Чтобы просмотреть запись хранилища, выполните `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>

Ответ содержит полную запись хранилища:

```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
}
```

## Добавление учётных данных

Поддерживаются две категории учётных данных:

* **Учётные данные MCP** (`mcp_oauth`, `static_bearer`): каждая запись учётных данных идентифицируется по `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`). Когда агент во время выполнения сессии подключается к серверу по этому URL, токен подставляется автоматически.
* **Переменные окружения** (`environment_variable`): каждая запись учётных данных идентифицируется по `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (имени переменной окружения) и хранится в песочнице в виде непрозрачного заполнителя. Когда агент инициирует исходящий запрос, непрозрачный заполнитель заменяется реальным секретом на выходе (egress). Агент никогда не видит значение секрета. Используйте этот вариант для любого сервиса, который выполняет аутентификацию через переменную окружения, например для CLI, SDK или прямых вызовов API.

Фактические значения учётных данных, которые вы передаёте (`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`)), считаются конфиденциальными полями только для записи и никогда не возвращаются в ответах API.

<Note>
  Учётные данные в виде переменных окружения (`environment_variable`) пока не поддерживаются с [самостоятельно размещаемыми песочницами](https://platform.claude.com/docs/ru/managed-agents/self-hosted-sandboxes).
</Note>

Чтобы получить такое же поведение в самостоятельно размещаемой песочнице, вы можете запустить собственный прокси, который заменяет значения-заполнители реальными секретами на выходе.

<Tabs>
  <Tab title="MCP OAuth">
    Используйте `mcp_oauth`, когда сервер MCP использует OAuth 2.0. Если вы передадите блок `refresh` (csharp, go: `Refresh`), Anthropic будет обновлять токен доступа от вашего имени по истечении его срока действия.

    Поле `refresh.token_endpoint_auth.type` указывает, как аутентифицировать вызов обновления:

    * `none`: публичный клиент
    * `client_secret_basic`: HTTP Basic-аутентификация с секретом клиента
    * `client_secret_post`: секрет клиента в теле 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>

    Укажите в `refresh.token_endpoint` (java, php: `refresh.tokenEndpoint`; csharp, go: `Refresh.TokenEndpoint`) конечную точку токенов того потока OAuth, который выдал токен обновления, поскольку Anthropic отправляет каждый запрос на обновление по этому URL, а поле нельзя изменить после создания учётных данных.
  </Tab>

  <Tab title="Статический bearer-токен MCP">
    Используйте `static_bearer`, когда сервер MCP принимает фиксированный bearer-токен (ключ API, персональный токен доступа или аналогичный). Процесс обновления не требуется.

    <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` для аутентификации во внешних сервисах через переменную окружения, например в CLI, SDK или при прямых вызовах API. Учётные данные в виде переменных окружения работают для клиентов, которые отправляют значение секрета дословно в исходящем запросе, поэтому перед настройкой проверьте критерии пригодности клиента на этой вкладке.

    Массив `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) в `networking` (csharp, go: `Networking`) определяет, для каких исходящих хостов может подставляться секрет. Используйте `"type": "limited"` с конкретным списком или `"type": "unrestricted"`, если вызывающая сторона обращается к доменам, которые невозможно перечислить заранее.

    Ограничение доменов настоятельно рекомендуется в целях безопасности и предотвращает передачу вашего ключа неавторизованным хостам.

    <Note>
      `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) в `networking` (csharp, go: `Networking`) для учётных данных хранилища определяет, какие запросы используют секрет, а не какие запросы разрешены. Чтобы агент действительно мог обратиться к домену, этот домен также должен быть разрешён на [уровне окружения](https://platform.claude.com/docs/ru/managed-agents/environments). Чтобы запрос с подстановкой секрета выполнился успешно, домен должен быть включён на обоих уровнях (либо через сетевой режим `unrestricted`, либо путём явного указания домена в `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)).
    </Note>

    Необязательное поле `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) ограничивает, куда подставляется секрет; полная семантика описана после примера.

    <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>

    Полезная нагрузка запросов часто формируется из содержимого, с которым работает агент, поэтому тело запроса представляет собой более широкую поверхность раскрытия. Большинство сервисов считывают ключ API из заголовка запроса, поэтому включение только `header` (csharp, go: `Header`) — более узкая конфигурация. Она ограничивает подстановку для этих учётных данных значениями заголовков запроса.

    Поле `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) учётных данных определяет, в какие части исходящего запроса подставляется секрет. Это необязательный объект, находящийся на одном уровне с `networking` (csharp, go: `Networking`), с двумя логическими полями: `header` (csharp, go: `Header`) (заголовки запроса) и `body` (csharp, go: `Body`) (тело запроса). `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) не зависит от `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) в `networking` (csharp, go: `Networking`): `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) ограничивает хосты, для которых подставляется секрет, а `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) ограничивает части запроса, в которые он подставляется.

    `injection_location` ведёт себя по-разному при создании и при обновлении:

    | Операция                  | Поведение `injection_location`                                                                                                                                                                                                      |
    | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Создание учётных данных   | Если вы передаёте объект, любое поле, которое вы опускаете внутри него, по умолчанию равно `false`: `{"header": true}` создаёт учётные данные только для заголовков. Опустите объект полностью — и будут включены оба расположения. |
    | Обновление учётных данных | Поля объединяются по отдельности: `{"body": false}` отключает подстановку в тело и оставляет `header` без изменений.                                                                                                                |

    У учётных данных должно быть включено хотя бы одно расположение, поэтому создание или обновление, которое отключило бы оба расположения, возвращает ошибку 400. Передача явного `null` для объекта `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) или для любого из его полей также возвращает ошибку 400 («omit the field instead»). Ответ всегда возвращает оба поля с их итоговыми значениями.

    Заполнитель в отключённом расположении не подставляется и не удаляется. Запрос отправляется третьей стороне с буквальной строкой непрозрачного заполнителя в этом расположении. Если к третьей стороне поступает запрос, содержащий буквальную строку заполнителя, значит, либо это расположение отключено для учётных данных, либо целевой хост не входит в `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) в `networking` (csharp, go: `Networking`) учётных данных.

    <Note>
      Учётные данные, созданные в Console, включают только внедрение в заголовки. Если ваш клиент отправляет секрет в теле запроса, например в form-encoded запросе токена, заполнитель передаётся буквально, и сервис отклоняет его с собственной ошибкой аутентификации. Включите внедрение в тело в форме Console при создании учётных данных или обновите учётные данные с помощью `{"injection_location": {"body": true}}`.
    </Note>

    Подстановка происходит на выходе, а не внутри песочницы. Всё, что обрабатывает учётные данные локально, видит непрозрачный заполнитель, а не реальное значение: клиенты, которые проверяют формат учётных данных при запуске, могут их отклонить, а клиенты, которые вычисляют подпись запроса на основе секрета (например, AWS SigV4), создают недействительную подпись. Учётные данные в виде переменных окружения работают для клиентов, которые отправляют значение секрета в исходящем запросе без изменений, в расположении, которое включено в `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) учётных данных.

    Подстановка выполняется только для исходящих запросов. Если клиент использует сохранённый секрет для получения сессионного токена (например, грант OAuth client-credentials), возвращённый токен поступает в песочницу в открытом виде. Для потоков, основанных на обмене, выполните обмен самостоятельно и сохраните полученный токен в хранилище.

    <Tip>
      Ограничьте ключ API только теми разрешениями, которые нужны агенту. Агент может делать всё, что позволяет ключ, поэтому ключ с более широкими разрешениями, чем необходимо, увеличивает радиус поражения, если агент поведёт себя неожиданно.
    </Tip>
  </Tab>
</Tabs>

Учётные данные сохраняются в том виде, в котором предоставлены, и не проверяются до момента выполнения сессии. Недействительные учётные данные проявляются как ошибка аутентификации или нижестоящая ошибка во время сессии, которая генерируется, но не блокирует продолжение сессии.

Ограничения:

* **Уникальный ключ в пределах хранилища.** `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) (учётные данные MCP) и `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (учётные данные в виде переменных окружения) должны быть уникальными среди активных учётных данных в хранилище. Создание дубликата возвращает 409.
* **Ключи неизменяемы.** Чтобы изменить `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) или `secret_name` (java, php: `secretName`; csharp, go: `SecretName`), архивируйте учётные данные и создайте новые.
* **Максимум 20 учётных данных на хранилище.**

## Ссылка на хранилище при создании сессии

Передайте `vault_ids` (java: `vaultIds`; php: `vaultIDs`; csharp: `VaultIds`; go: `VaultIDs`) при создании сессии:

<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>

Поведение во время выполнения:

* Если ни одни учётные данные MCP не совпадают по `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`), выполняется попытка подключения без аутентификации, которая завершится ошибкой, если сервер требует аутентификацию.
* Если несколько хранилищ содержат подходящие учётные данные, побеждает первое хранилище с совпадением.
* В [мультиагентных сессиях](https://platform.claude.com/docs/ru/managed-agents/multiagent-orchestration) учётные данные хранилища применяются к каждому потоку. Агент, в собственном определении которого объявлен соответствующий сервер MCP, аутентифицируется с помощью этих учётных данных. См. [Подключение агентов к серверам MCP](https://platform.claude.com/docs/ru/managed-agents/multiagent-orchestration#connect-agents-to-mcp-servers).

## Ротация учётных данных

Значения секретов, `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) и (для учётных данных в виде переменных окружения) `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) можно обновлять. Обновления `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) объединяются по полям, как описано на вкладке «Переменная окружения» раздела [Добавление учётных данных](https://platform.claude.com/docs/ru/managed-agents/vaults#add-a-credential). Для работающей сессии обновление `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) распространяется так же, как ротация секрета: учётные данные сессии повторно разрешаются без перезапуска, как описано в разделе [Жизненный цикл учётных данных](https://platform.claude.com/docs/ru/managed-agents/vaults#credential-lifecycle), и обновлённые расположения применяются к последующим исходящим запросам сессии. Структурные поля (`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`)) блокируются после создания. Чтобы изменить их, архивируйте учётные данные и создайте новые.

<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>

## Жизненный цикл учётных данных

Учётные данные периодически разрешаются повторно — как во время сессии, так и в течение жизненного цикла хранилища. Это гарантирует, что ротация, архивирование или удаление учётных данных распространяются на выполняющиеся сессии без перезапуска.

Чтобы получать уведомления об архивировании, удалении или сбое обновления учётных данных, вы можете подписаться на [вебхуки](https://platform.claude.com/docs/ru/managed-agents/webhooks) хранилищ и учётных данных, связанные с этими изменениями жизненного цикла.

| Событие                           | Триггер                                                                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `vault.archived`                  | Хранилище архивировано. Для каждых входящих в него учётных данных также генерируется событие `vault_credential.archived`. |
| `vault.deleted`                   | Хранилище удалено. Для каждых входящих в него учётных данных также генерируется событие `vault_credential.deleted`.       |
| `vault_credential.archived`       | Учётные данные архивированы — напрямую или в результате архивирования хранилища.                                          |
| `vault_credential.deleted`        | Учётные данные удалены — напрямую или в результате удаления хранилища.                                                    |
| `vault_credential.refresh_failed` | Учётные данные `mcp_oauth` не удаётся обновить (недействительный refresh-токен или неустранимая ошибка от сервера OAuth). |

<Note>
  Это неполный список вебхуков; полный список см. в разделе [Подписка на вебхуки](https://platform.claude.com/docs/ru/managed-agents/webhooks).
</Note>

Для учётных данных `mcp_oauth` повторное разрешение также обновляет токен доступа, если срок его действия истёк. Если обновление не удаётся, генерируется событие `vault_credential.refresh_failed`.

### Диагностика сбоя обновления OAuth

Чтобы выяснить причину сбоя обновления, вызовите `POST /v1/vaults/{vault_id}/credentials/{credential_id}/mcp_oauth_validate` (или `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(...)`) в SDK). Результат поможет решить, как обработать сбой: правильное действие зависит от типа ошибки.

Поле верхнего уровня `status` (csharp, go: `Status`) подсказывает, что делать дальше:

* `valid`: токен работает; никаких действий не требуется.
* `invalid`: грант утрачен или сервер OAuth отклонил обновление с ошибкой 4xx. Предложите конечному пользователю пройти авторизацию повторно.
* `unknown`: временная ошибка (5xx, 429 или сетевой сбой). Подождите и повторите попытку.

<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>

Ответ представляет собой объект `vault_credential_validation`. `mcp_probe` содержит шаг рукопожатия MCP, на котором произошёл сбой; `refresh` содержит результат попытки обновления.

```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
  }
}
```

## Другие операции

* **Список хранилищ или учётных данных:** с разбивкой на страницы, сначала самые новые. Архивированные записи по умолчанию исключаются (передайте `include_archived=true`, чтобы включить их).
* **Архивирование хранилища:** `POST /v1/vaults/{id}/archive`. Каскадно применяется ко всем учётным данным. Секреты уничтожаются; записи сохраняются для аудита. Будущие сессии, ссылающиеся на это хранилище, завершаются ошибкой; выполняющиеся сессии продолжают работу.
* **Архивирование учётных данных:** `POST /v1/vaults/{id}/credentials/{cred_id}/archive`. Уничтожает полезную нагрузку секрета; ключ учётных данных (`mcp_server_url` или `secret_name`) остаётся видимым и освобождается для замещающих учётных данных.
* **Удаление хранилища или учётных данных:** безвозвратное удаление. Запись не сохраняется. Используйте архивирование, если вам нужен аудиторский след.
