Аутентификация с помощью хранилищ
Регистрируйте учётные данные для каждого пользователя при создании сессий.
«Vaults» (хранилища) и «credentials» (учётные данные) — это примитивы аутентификации, которые позволяют вам один раз зарегистрировать учётные данные для сторонних сервисов и ссылаться на них по идентификатору при создании сессии. Это означает, что вам не нужно поддерживать собственное хранилище секретов, передавать токены при каждом вызове или терять информацию о том, от имени какого конечного пользователя действовал агент.
Ссылка на хранилище — это параметр уровня сессии, поэтому вы можете управлять своим продуктом на уровне ресурса agent, а своими пользователями — на уровне ресурса session.
Создание хранилища
Хранилище — это набор credentials, связанных с конечным пользователем. Задайте ему display_name и при необходимости пометьте его с помощью metadata, чтобы вы могли сопоставить его с вашими собственными записями о пользователях.
vault = client.beta.vaults.create(
display_name="Alice",
metadata={"external_user_id": "usr_abc123"},
)
print(vault.id) # "vlt_01ABC..."Ответ содержит полную запись хранилища:
{
"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(имени переменной окружения) и хранятся в песочнице в виде непрозрачного заполнителя. Когда агент инициирует исходящий запрос, непрозрачный заполнитель заменяется реальным секретом на выходе (egress). Агент никогда не видит значение секрета. Используйте это для любого сервиса, который аутентифицируется через переменную окружения, например CLI, SDK или прямые вызовы API.
Фактические значения учётных данных, которые вы предоставляете (token, access_token, refresh_token, client_secret, secret_value), рассматриваются как конфиденциальные поля, доступные только для записи, и никогда не возвращаются в ответах API.
Используйте mcp_oauth, когда сервер MCP использует OAuth 2.0. Если вы предоставите блок 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, а изменить это поле после создания учётных данных нельзя.
Используйте static_bearer, когда сервер MCP принимает фиксированный bearer-токен (ключ API, персональный токен доступа или аналогичный). Процесс обновления не требуется.
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. Передача явного null для объекта injection_location или для любого из полей также возвращает ошибку 400 («omit the field instead»). Ответ всегда возвращает оба поля с их итоговыми значениями.
Заполнитель в отключённом расположении не подставляется и не удаляется. Запрос отправляется третьей стороне с буквальной строкой непрозрачного заполнителя в этом расположении. Если запрос поступает третьей стороне с буквальной строкой заполнителя, значит, либо это расположение отключено для учётных данных, либо целевой хост не покрывается networking.allowed_hosts учётных данных.
Подстановка происходит на выходе (egress), а не внутри песочницы. Всё, что обрабатывает учётные данные локально, видит непрозрачный заполнитель, а не реальное значение: клиенты, которые проверяют формат учётных данных при запуске, могут отклонить его, а клиенты, которые вычисляют подпись запроса на основе секрета (например, AWS SigV4), создают недействительную подпись. Учётные данные в виде переменных окружения работают для клиентов, которые отправляют значение секрета дословно в исходящем запросе, в расположении, включённом в injection_location учётных данных.
Подстановка выполняется только для исходящих запросов. Если клиент использует сохранённый секрет для получения сессионного токена (например, грант OAuth client-credentials), возвращённый токен поступает в песочницу в открытом виде. Для потоков, основанных на обмене, выполните обмен самостоятельно и сохраните полученный токен в хранилище.
Учётные данные сохраняются в том виде, в котором предоставлены, и не проверяются до момента выполнения сессии. Недействительные учётные данные проявляются как ошибка аутентификации или нижестоящая ошибка во время сессии, которая генерируется, но не блокирует продолжение сессии.
Ограничения:
- Уникальный ключ в пределах хранилища.
mcp_server_url(учётные данные MCP) иsecret_name(учётные данные в виде переменных окружения) должны быть уникальными среди активных учётных данных в хранилище. Создание дубликата возвращает 409. - Ключи неизменяемы. Чтобы изменить
mcp_server_urlилиsecret_name, архивируйте учётные данные и создайте новые. - Максимум 20 учётных данных на хранилище.
Ссылка на хранилище при создании сессии
Передайте 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, выполняется попытка подключения без аутентификации, которая завершится ошибкой, если сервер требует аутентификации. - Если несколько хранилищ содержат подходящие учётные данные, побеждает первое хранилище с совпадением.
- В мультиагентных сессиях учётные данные хранилища применяются к каждому потоку. Агент, в собственном определении которого объявлен соответствующий сервер 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.archived | Хранилище архивировано. Для каждых входящих в него учётных данных также генерируется событие vault_credential.archived. |
vault.deleted | Хранилище удалено. Для каждых входящих в него учётных данных также генерируется событие vault_credential.deleted. |
vault_credential.archived | Учётные данные архивированы — напрямую или в результате архивирования хранилища. |
vault_credential.deleted | Учётные данные удалены — напрямую или в результате удаления хранилища. |
vault_credential.refresh_failed | Учётные данные mcp_oauth не удаётся обновить (недействительный refresh-токен или неустранимая ошибка от сервера OAuth). |
Для учётных данных 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(...) в SDK). Результат поможет решить, как обработать сбой: правильное действие зависит от типа ошибки.
Поле верхнего уровня 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
}
}Другие операции
- Список хранилищ или учётных данных: с разбивкой на страницы, сначала самые новые. Архивированные записи по умолчанию исключаются (передайте
include_archived=true, чтобы включить их). - Архивирование хранилища:
POST /v1/vaults/{id}/archive. Каскадно применяется ко всем учётным данным. Секреты уничтожаются; записи сохраняются для аудита. Будущие сессии, ссылающиеся на это хранилище, завершаются ошибкой; выполняющиеся сессии продолжают работу. - Архивирование учётных данных:
POST /v1/vaults/{id}/credentials/{cred_id}/archive. Уничтожает полезную нагрузку секрета; ключ учётных данных (mcp_server_urlилиsecret_name) остаётся видимым и освобождается для замещающих учётных данных. - Удаление хранилища или учётных данных: безвозвратное удаление. Запись не сохраняется. Используйте архивирование, если вам нужен аудиторский след.
Was this page helpful?