使用 vault 进行身份验证
在创建会话时注册每个用户的凭证。
Vault(保管库)和 credential(凭证)是身份验证原语,让您可以一次性注册第三方服务的凭证,并在创建会话时通过 ID 引用它们。这意味着您无需运行自己的密钥存储、无需在每次调用时传输令牌,也不会丢失代理代表哪个最终用户执行操作的记录。
vault 引用是一个按会话设置的参数,因此您可以在 agent 资源粒度上管理您的产品,在 session 资源粒度上管理您的用户。
创建 vault
vault 是与某个最终用户关联的 credentials 集合。为其指定一个 display_name,并可选择使用 metadata 进行标记,以便您将其映射回自己的用户记录。
vault = client.beta.vaults.create(
display_name="Alice",
metadata={"external_user_id": "usr_abc123"},
)
print(vault.id) # "vlt_01ABC..."响应是完整的 vault 记录:
{
"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作为键。当代理在会话运行时连接到该 URL 的服务器时,令牌会自动注入。 - 环境变量(
environment_variable):每个凭证以secret_name(环境变量名称)作为键,并以不透明占位符的形式存储在沙箱中。当代理发起出站请求时,不透明占位符会在出口处被替换为真实密钥。代理永远不会看到密钥值。对于任何通过环境变量进行身份验证的服务(例如 CLI、SDK 或直接 API 调用),请使用此类型。
您提供的实际凭证值(token、access_token、refresh_token、client_secret、secret_value)被视为敏感的只写字段,永远不会在 API 响应中返回。
当 MCP 服务器使用 OAuth 2.0 时,请使用 mcp_oauth。如果您提供了 refresh 块,Anthropic 会在访问令牌过期时代您刷新。
refresh.token_endpoint_auth.type 字段指示如何对刷新调用进行身份验证:
none:公共客户端client_secret_basic:使用客户端密钥的 HTTP Basic 身份验证client_secret_post:客户端密钥位于 POST 请求体中
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..."},
},
},
)请将 refresh.token_endpoint 设置为签发该刷新令牌的 OAuth 流程的令牌端点,因为 Anthropic 会将每个刷新请求发送到该 URL,并且该字段在凭证创建后无法更改。
当 MCP 服务器接受固定的 bearer 令牌(API 密钥、个人访问令牌或类似令牌)时,请使用 static_bearer。无需刷新流程。
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",
},
)使用 environment_variable 通过环境变量向外部服务进行身份验证,例如 CLI、SDK 或直接 API 调用。环境变量凭证适用于在出站请求中原样发送密钥值的客户端,因此在配置之前,请先查看本标签页中的客户端适用条件。
networking.allowed_hosts 数组控制密钥可以被替换到哪些出站主机。使用 "type": "limited" 并指定具体列表;如果调用方会访问您无法预先枚举的域名,则使用 "type": "unrestricted"。
出于安全考虑,强烈建议限制域名,这可以防止您的密钥被共享给未经授权的主机。
可选的 injection_location 字段限定密钥被替换的位置;完整语义见示例之后的说明。
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请求负载通常由代理正在处理的内容组装而成,因此请求体是更广的暴露面。大多数服务从请求头中读取 API 密钥,因此仅启用 header 是更窄的配置。它将该凭证的替换范围限定为请求头的值。
凭证的 injection_location 控制密钥被替换到出站请求的哪些部分。它是一个可选对象,与 networking 同级,包含两个布尔字段:header(请求头)和 body(请求体)。injection_location 独立于 networking.allowed_hosts:allowed_hosts 限定密钥被替换到哪些主机,而 injection_location 限定密钥被替换到请求的哪些部分。
injection_location 在创建和更新时的行为不同:
| 操作 | injection_location 行为 |
|---|---|
| 创建凭证 | 如果您提供了该对象,其中省略的任何字段默认为 false:{"header": true} 会创建一个仅限请求头的凭证。完全省略该对象则两个位置都会启用。 |
| 更新凭证 | 字段逐个合并:{"body": false} 会禁用请求体替换,并保持 header 不变。 |
凭证必须至少启用一个位置,因此会导致两个位置都被禁用的创建或更新操作将返回 400 错误。为 injection_location 对象或其中任一字段显式传递 null 也会返回 400 错误("omit the field instead",即请改为省略该字段)。响应始终返回两个字段及其解析后的值。
位于已禁用位置的占位符既不会被替换也不会被移除。请求会带着该位置上的字面不透明占位符字符串发送给第三方。如果到达第三方的请求包含字面占位符字符串,则要么该凭证的该位置已被禁用,要么目标主机未被该凭证的 networking.allowed_hosts 覆盖。
替换发生在出口处,而不是在沙箱内部。任何在本地处理凭证的程序看到的都是不透明占位符,而不是真实值:在启动时验证凭证格式的客户端可能会拒绝它,而根据密钥计算请求签名的客户端(例如 AWS SigV4)会生成无效签名。环境变量凭证适用于在出站请求中、在凭证的 injection_location 所启用的位置原样发送密钥值的客户端。
替换仅针对出站方向。如果客户端使用存储的密钥获取会话令牌(例如 OAuth 客户端凭证授权),返回的令牌会以未脱敏的形式到达沙箱。对于基于交换的流程,请自行执行交换,并将生成的令牌存储在 vault 中。
凭证按提供的原样存储,直到会话运行时才会进行验证。无效凭证会在会话期间表现为身份验证错误或下游错误,该错误会被发出,但不会阻止会话继续进行。
约束:
- 每个 vault 内键唯一。
mcp_server_url(MCP 凭证)和secret_name(环境变量凭证)在 vault 的活动凭证中必须唯一。创建重复项会返回 409。 - 键不可变。 要更改
mcp_server_url或secret_name,请归档该凭证并创建一个新凭证。 - 每个 vault 最多 20 个凭证。
在创建会话时引用 vault
创建会话时传递 vault_ids:
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
vault_ids=[vault.id],
title="Alice's Slack digest",
)运行时行为:
- 当没有 MCP 凭证按
mcp_server_url匹配时,会尝试以未经身份验证的方式连接,如果服务器要求身份验证则会报错。 - 当多个 vault 包含匹配的凭证时,第一个匹配的 vault 优先。
- 在多代理会话中,vault 凭证适用于每个线程。自身定义中声明了匹配 MCP 服务器的代理会使用这些凭证进行身份验证。请参阅将代理连接到 MCP 服务器。
轮换凭证
密钥值、display_name 以及(环境变量凭证上的)injection_location 可以更新。injection_location 的更新按字段合并,如添加凭证的"环境变量"标签页中所述。对于正在运行的会话,injection_location 更新的传播方式与密钥轮换相同:会话的凭证会在无需重启的情况下重新解析(如凭证生命周期中所述),更新后的位置将应用于会话后续的出站请求。结构性字段(mcp_server_url、secret_name、token_endpoint、client_id)在创建后即被锁定。要更改它们,请归档该凭证并创建一个新凭证。
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-..."},
},
)凭证生命周期
凭证会定期重新解析,无论是在会话期间还是在 vault 生命周期中。这确保了凭证的轮换、归档或删除能够在无需重启的情况下传播到正在运行的会话。
如需在凭证被归档、删除或刷新失败时收到通知,您可以订阅与这些生命周期变更相关的 vault 和凭证 webhook。
| 事件 | 触发条件 |
|---|---|
vault.archived | Vault 已归档。同时会为每个底层凭证发出一个 vault_credential.archived 事件。 |
vault.deleted | Vault 已删除。同时会为每个底层凭证发出一个 vault_credential.deleted 事件。 |
vault_credential.archived | 凭证已归档,可能是直接归档,也可能是 vault 归档的结果。 |
vault_credential.deleted | 凭证已删除,可能是直接删除,也可能是 vault 删除的结果。 |
vault_credential.refresh_failed | mcp_oauth 凭证无法刷新(刷新令牌无效,或 OAuth 服务器返回不可恢复的错误)。 |
对于 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(...))。这可以帮助您决定如何处理该失败;正确的处理方式取决于错误类型。
顶层 status 告诉您下一步该做什么:
valid:令牌有效;无需操作。invalid:授权已失效,或 OAuth 服务器以 4xx 拒绝了刷新。提示最终用户重新授权。unknown:暂时性错误(5xx、429 或网络故障)。等待并重试。
validation = client.beta.vaults.credentials.mcp_oauth_validate(
credential.id,
vault_id=vault.id,
)
print(validation.status) # "valid", "invalid", or "unknown"响应是一个 vault_credential_validation 对象。mcp_probe 包含失败的 MCP 握手步骤;refresh 包含所尝试刷新的结果。
{
"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
}
}其他操作
- 列出 vault 或凭证: 分页返回,最新的在前。默认排除已归档的记录(传递
include_archived=true可将其包含在内)。 - 归档 vault:
POST /v1/vaults/{id}/archive。级联到所有凭证。密钥会被清除;记录会保留以供审计。之后引用此 vault 的会话将失败;正在运行的会话会继续。 - 归档凭证:
POST /v1/vaults/{id}/credentials/{cred_id}/archive。清除密钥负载;凭证键(mcp_server_url或secret_name)仍然可见,并被释放以供替换凭证使用。 - 删除 vault 或凭证: 硬删除。记录不会保留。如果您需要审计记录,请使用归档。
Was this page helpful?