---
title: 볼트로 인증하기
url: https://platform.claude.com/docs/ko/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
---

"Vault"(볼트)와 "credential"(자격 증명)은 서드파티 서비스의 자격 증명을 한 번 등록하고 세션 생성 시 ID로 참조할 수 있게 해주는 인증 기본 요소입니다. 즉, 자체 시크릿 저장소를 운영하거나, 매 호출마다 토큰을 전송하거나, 에이전트가 어떤 최종 사용자를 대신하여 동작했는지 추적하지 못하게 되는 일이 없습니다.

볼트 참조는 세션별 매개변수이므로, 제품은 `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/ko/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/ko/managed-agents/self-hosted-sandboxes)에서 지원되지 않습니다.
</Note>

자체 호스팅 샌드박스에서 동일한 동작을 구현하려면, 이그레스 시점에 플레이스홀더 값을 실제 시크릿으로 대체하는 자체 프록시를 실행할 수 있습니다.

<Tabs>
  <Tab title="MCP OAuth">
    MCP 서버가 OAuth 2.0을 사용하는 경우 `mcp_oauth`를 사용하세요. `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="MCP 정적 베어러">
    MCP 서버가 고정된 베어러 토큰(API 키, 개인 액세스 토큰 등)을 허용하는 경우 `static_bearer`를 사용하세요. 갱신 플로우가 필요하지 않습니다.

    <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="환경 변수">
    CLI, SDK 또는 직접 API 호출과 같이 환경 변수를 통해 외부 서비스에 인증하려면 `environment_variable`을 사용하세요. 환경 변수 자격 증명은 아웃바운드 요청에 시크릿 값을 그대로 전송하는 클라이언트에서 동작하므로, 구성하기 전에 이 탭의 클라이언트 적격 기준을 확인하세요.

    `networking` (csharp, go: `Networking`)의 `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) 배열은 시크릿이 대체될 수 있는 아웃바운드 호스트를 제어합니다. 특정 목록과 함께 `"type": "limited"`를 사용하거나, 호출자가 미리 열거할 수 없는 도메인에 접근하는 경우 `"type": "unrestricted"`를 사용하세요.

    보안을 위해 도메인을 제한하는 것을 강력히 권장하며, 이는 키가 승인되지 않은 호스트와 공유되는 것을 방지합니다.

    <Note>
      볼트 자격 증명의 `networking` (csharp, go: `Networking`)에 있는 `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)는 어떤 요청이 시크릿을 사용하는지를 제어하며, 어떤 요청이 허용되는지를 제어하지는 않습니다. 에이전트가 실제로 도메인에 접근하려면 해당 도메인이 [환경 수준](https://platform.claude.com/docs/ko/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`)은 `networking` (csharp, go: `Networking`)의 `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)와 독립적입니다. `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 오류를 반환합니다. `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) 객체나 두 필드 중 하나에 명시적으로 `null`을 전달해도 400 오류("omit the field instead")가 반환됩니다. 응답은 항상 두 필드를 확정된 값과 함께 반환합니다.

    비활성화된 위치에 있는 플레이스홀더는 대체되지도 제거되지도 않습니다. 요청은 해당 위치에 불투명한 플레이스홀더 문자열이 그대로 포함된 채 서드파티로 전송됩니다. 리터럴 플레이스홀더 문자열이 포함된 요청이 서드파티에 도착했다면, 해당 자격 증명에서 그 위치가 비활성화되어 있거나 대상 호스트가 자격 증명의 `networking` (csharp, go: `Networking`)에 있는 `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)에 포함되지 않은 것입니다.

    <Note>
      Console에서 생성된 자격 증명은 헤더 주입만 활성화합니다. 클라이언트가 폼 인코딩된 토큰 요청과 같이 요청 본문에 시크릿을 전송하는 경우, 플레이스홀더가 리터럴 그대로 통과되고 서비스는 자체 인증 오류로 이를 거부합니다. 자격 증명을 생성할 때 Console 폼에서 본문 주입을 활성화하거나, `{"injection_location": {"body": true}}`로 자격 증명을 업데이트하세요.
    </Note>

    대체는 샌드박스 내부가 아니라 이그레스 시점에 이루어집니다. 자격 증명을 로컬에서 처리하는 모든 것은 실제 값이 아닌 불투명한 플레이스홀더를 보게 됩니다. 시작 시 자격 증명 형식을 검증하는 클라이언트는 이를 거부할 수 있으며, 시크릿으로부터 요청 서명을 계산하는 클라이언트(예: AWS SigV4)는 유효하지 않은 서명을 생성합니다. 환경 변수 자격 증명은 자격 증명의 `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`)이 활성화한 위치에서, 아웃바운드 요청에 시크릿 값을 그대로 전송하는 클라이언트에서 작동합니다.

    대체는 아웃바운드 방향으로만 이루어집니다. 클라이언트가 저장된 시크릿을 사용하여 세션 토큰을 가져오는 경우(예: OAuth 클라이언트 자격 증명 그랜트), 반환된 토큰은 가려지지 않은 상태로 샌드박스에 도착합니다. 교환 기반 플로우의 경우, 직접 교환을 수행하고 결과 토큰을 볼트에 저장하세요.

    <Tip>
      API 키의 범위를 에이전트에 필요한 권한으로만 한정하세요. 에이전트는 키가 허용하는 모든 작업을 수행할 수 있으므로, 필요 이상으로 넓은 권한을 가진 키는 에이전트가 예상치 못하게 동작할 경우 피해 범위를 증가시킵니다.
    </Tip>
  </Tab>
</Tabs>

자격 증명은 제공된 그대로 저장되며 세션 런타임까지 검증되지 않습니다. 유효하지 않은 자격 증명은 세션 중 인증 오류 또는 다운스트림 오류로 나타나며, 이 오류는 발생(emit)되지만 세션이 계속 진행되는 것을 막지는 않습니다.

제약 사항:

* **볼트당 고유 키.** `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_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`)로 일치하는 MCP 자격 증명이 없으면, 인증 없이 연결을 시도하며 서버가 인증을 요구하는 경우 오류가 발생합니다.
* 여러 볼트에 일치하는 자격 증명이 있는 경우, 일치 항목이 있는 첫 번째 볼트가 우선합니다.
* [멀티에이전트 세션](https://platform.claude.com/docs/ko/managed-agents/multiagent-orchestration)에서는 볼트 자격 증명이 모든 스레드에 적용됩니다. 자체 정의에서 일치하는 MCP 서버를 선언한 에이전트는 이 자격 증명으로 인증합니다. [에이전트를 MCP 서버에 연결하기](https://platform.claude.com/docs/ko/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/ko/managed-agents/vaults#add-a-credential)의 환경 변수 탭에 설명된 대로 필드별로 병합됩니다. 실행 중인 세션의 경우, `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) 업데이트는 시크릿 교체와 동일한 방식으로 전파됩니다. [자격 증명 수명 주기](https://platform.claude.com/docs/ko/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/ko/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` 자격 증명을 갱신할 수 없음(유효하지 않은 리프레시 토큰, 또는 OAuth 서버의 복구 불가능한 오류). |

<Note>
  이는 웹훅의 전체 목록이 아닙니다. 전체 목록은 [웹훅 구독하기](https://platform.claude.com/docs/ko/managed-agents/webhooks)를 참조하세요.
</Note>

`mcp_oauth` 자격 증명의 경우, 재확정 시 액세스 토큰이 만료되었다면 토큰도 갱신합니다. 갱신에 실패하면 `vault_credential.refresh_failed` 이벤트가 발생합니다.

### OAuth 갱신 실패 진단하기

갱신이 실패한 이유를 진단하려면 `POST /v1/vaults/{vault_id}/credentials/{credential_id}/mcp_oauth_validate`(또는 SDK에서 `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(...)`))를 호출하세요. 이를 통해 실패를 어떻게 처리할지 결정할 수 있으며, 적절한 조치는 오류 유형에 따라 달라집니다.

최상위 `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`)는 계속 표시되며 대체 자격 증명을 위해 해제됩니다.
* **볼트 또는 자격 증명 삭제:** 영구 삭제입니다. 레코드가 보존되지 않습니다. 감사 추적이 필요하면 보관 처리를 사용하세요.
