> ## Documentation Index
> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Проверка идентификации сеанса в самостоятельно размещаемых окружениях

> Проверьте JWT CLAUDE_CODE_SESSION_ACCESS_TOKEN, чтобы сервисы в вашей сети могли доверять запросам от сеансов в вашем самостоятельно размещаемом окружении.

<Note>
  Самостоятельно размещаемые окружения находятся в публичной бета-версии на планах Team и Enterprise; [владелец](/docs/ru/cloud-environments#organization-shared-environments) включает их, активируя **Allow self-hosted environments** на [странице администратора **Cloud environments**](https://claude.ai/admin-settings/cloud-environments). На этой странице рассматривается проверка идентификации сеанса; см. [краткое руководство](/docs/ru/self-hosted-environments-quickstart) для настройки и [Deploy to production](/docs/ru/self-hosted-environments-deploy) для рецептов флота.
</Note>

[Самостоятельно размещаемое окружение](/docs/ru/self-hosted-environments) позволяет сеансам [Claude Code в веб-интерфейсе](/docs/ru/claude-code-on-the-web) работать на инфраструктуре, которой вы управляете, вместо инфраструктуры Anthropic. Поскольку сеанс работает внутри вашей сети, Claude может напрямую вызывать ваши внутренние сервисы. Эти сервисы должны иметь способ подтвердить, что запрос поступил от сеанса Claude Code в вашем окружении, и определить идентификацию пользователя или сервиса, который создал этот сеанс.

Каждый сеанс в самостоятельно размещаемом окружении получает подписанный JSON Web Token (JWT) в переменной окружения `CLAUDE_CODE_SESSION_ACCESS_TOKEN`. Сеанс представляет токен как любые учетные данные носителя; например, скрипт, который запускает Claude, может вызвать ваш сервис с помощью `curl -H "Authorization: Bearer $CLAUDE_CODE_SESSION_ACCESS_TOKEN"`. Anthropic подписывает токен и публикует ключи проверки на публичной конечной точке JWKS. Ваши сервисы получают эти ключи, проверяют подпись и читают утверждения, чтобы решить, какой доступ предоставить.

<h2 id="the-session-token">
  Токен сеанса
</h2>

Прежде чем писать код проверки, знайте, что устанавливает токен и какую форму будет иметь ваша библиотека JWT.

<h3 id="what-the-token-proves">
  Что доказывает токен
</h3>

Действительный токен устанавливает некоторые факты и намеренно не устанавливает другие:

* **Доказывает**: Anthropic выдала токен для конкретного сеанса в конкретном окружении и как был создан сеанс: пользователем в вашей организации или идентификацией сервиса вашей организации, что является способом запуска [сеансов канала Claude Tag](https://claude.com/docs/claude-tag/concepts/agent-identity)
* **Не доказывает**: какой процесс на хосте runner представляет его. Токен находится в переменной окружения внутри сеанса, поэтому любой код, который запускает Claude, и любой инструмент или MCP сервер, который запускает сеанс, могут его прочитать и представить.

Два следствия для ваших сервисов:

* Проверьте утверждение `aud` против вашего ID окружения, значения `ccpool_...`, показанного с вашим окружением на [странице администратора **Cloud environments**](https://claude.ai/admin-settings/cloud-environments), чтобы отклонить токены, выданные для любого другого окружения организации.
* Ограничьте учетные данные, которые вы получаете из токена, тем, что может делать один сеанс кодирования, а не всем, что может делать создатель сеанса. См. [Ограничение полученных учетных данных](#scope-derived-credentials).

<h3 id="token-format">
  Формат токена
</h3>

Значение `CLAUDE_CODE_SESSION_ACCESS_TOKEN` имеет префикс `sk-ant-cc-`, за которым следует стандартный трехчастный JWT:

```text theme={null}
sk-ant-cc-<base64url header>.<base64url payload>.<base64url signature>
```

Удалите префикс перед передачей значения в библиотеку JWT. Токены, выданные для размещаемых в облаке сеансов Anthropic, имеют префикс `sk-ant-si-` и подписаны другим набором ключей, поэтому отклоните любое значение, которое не начинается с `sk-ant-cc-`.

Алгоритм подписи — это `ES256`, который является ECDSA на кривой P-256 с SHA-256. Заголовок токена содержит `kid`, который идентифицирует, какой ключ в JWKS его подписал.

<h2 id="verify-the-token">
  Проверка токена
</h2>

Проверка выполняется в одном из двух мест. Сервисы в вашей сети проверяют токен криптографически против опубликованных ключей Anthropic, а скрипты-обертки внутри сеанса могут использовать встроенный декодер бинарного файла runner.

<h3 id="verify-the-token-from-your-service">
  Проверка токена из вашего сервиса
</h3>

Anthropic публикует ключи проверки на публичной, не требующей аутентификации конечной точке:

```text theme={null}
https://api.anthropic.com/v1/code/.well-known/jwks.json
```

Ответ — это стандартный [JSON Web Key Set](https://www.rfc-editor.org/rfc/rfc7517). Anthropic периодически ротирует ключи подписи, и ключи до ротации остаются в наборе достаточно долго, чтобы токены, которые они подписали, продолжали проверяться, поэтому не привязывайте один ключ. Конечная точка устанавливает `Cache-Control: public, max-age=300`, поэтому кэширование набора ключей и повторная выборка каждые пять минут безопасны.

Проверьте каждый входящий токен против этих проверок:

<Steps>
  <Step title="Проверьте префикс">
    Отклоните значение, если оно не начинается с `sk-ant-cc-`, затем удалите этот префикс. Остаток — это стандартный компактный JWT.
  </Step>

  <Step title="Проверьте подпись">
    Получите JWKS, выберите ключ, чей `kid` совпадает с заголовком токена, и проверьте подпись `ES256`. Отклоните токены, чей заголовок `alg` не является `ES256`. Если токен поступает с `kid`, которого нет в вашем кэшированном наборе ключей, получите JWKS еще раз перед отклонением: после ротации новые токены подписаны ключом, который ваш кэшированный набор еще не имеет.
  </Step>

  <Step title="Проверьте издателя">
    Отклоните токен, если `iss` не является ровно `ccr`.
  </Step>

  <Step title="Проверьте аудиторию против вашего окружения">
    Утверждение `aud` — это массив. Отклоните токен, если он не содержит ваш ID окружения, который имеет форму `ccpool_...`. ID окружения показан в диалоговом окне деталей вашего окружения на [странице администратора **Cloud environments**](https://claude.ai/admin-settings/cloud-environments) и отображается как утверждение `ccr:pool_id` в любых токенах сеанса окружения. Эта проверка — это то, что ограничивает токен вашим окружением и отклоняет токены, выданные другим организациям.
  </Step>

  <Step title="Проверьте роль">
    Отклоните токен, если `ccr:role` не является ровно `session_worker`. Другие токены, выданные для самостоятельно размещаемых окружений, такие как секреты окружения, токены runner и рабочие заказы, подписаны тем же набором ключей, но имеют разные роли.
  </Step>

  <Step title="Проверьте срок действия">
    Отклоните токен, если `exp` находится в прошлом. Anthropic выдает токены сеанса с четырехчасовым сроком действия по умолчанию и максимум восемь часов. Runner обновляет токен перед истечением срока и отправляет новое значение в сеанс, поэтому подпроцессы, которые Claude запускает после обновления, наследуют его. Таким образом, один сеанс может представить несколько различных действительных токенов вашему сервису в течение его жизни.
  </Step>

  <Step title="Прочитайте идентификацию">
    Идентификация создающего пользователя находится в утверждении `act`: `act.sub` — это его ID пользователя Anthropic в префиксной форме `user:<id>`, а `act.email`, когда создающая поверхность записала его, — это его адрес электронной почты. Сеансы, которые создает идентификация сервиса вашей организации, включая сеансы канала Claude Tag, вместо этого содержат субъект `agent:`, поэтому рассматривайте сеанс как созданный пользователем только когда `act.sub` содержит префикс `user:`, а не проверяя, отсутствуют ли утверждения идентификации. См. [справочник утверждений](#claims-reference) для полной структуры и плоских дублирующихся утверждений.
  </Step>
</Steps>

Проверки напрямую соответствуют стандартным библиотекам JWT. Примеры ниже реализуют полную последовательность в Node.js с [`jose`](https://www.npmjs.com/package/jose), которая обрабатывает получение JWKS, кэширование и выбор `kid`, и в Python с [`PyJWT`](https://pyjwt.readthedocs.io/) и его встроенным клиентом JWKS.

<Tabs>
  <Tab title="Node.js (jose)">
    ```typescript theme={null}
    import { createRemoteJWKSet, jwtVerify } from "jose";

    const JWKS = createRemoteJWKSet(
      new URL("https://api.anthropic.com/v1/code/.well-known/jwks.json")
    );

    const PREFIX = "sk-ant-cc-";
    const EXPECTED_POOL_ID = "ccpool_...";

    export async function verifySessionToken(raw: string) {
      if (!raw.startsWith(PREFIX)) {
        throw new Error("not a self-hosted runner session token");
      }
      const jwt = raw.slice(PREFIX.length);

      const { payload } = await jwtVerify(jwt, JWKS, {
        issuer: "ccr",
        audience: EXPECTED_POOL_ID,
        algorithms: ["ES256"],
      });

      if (payload["ccr:role"] !== "session_worker") {
        throw new Error("token is not a session_worker token");
      }

      const act = payload.act as { email?: string; sub?: string };
      return {
        sessionId: payload["ccr:session_id"] as string,
        poolId: payload["ccr:pool_id"] as string,
        orgId: payload["ccr:org_id"] as string,
        creatorEmail: act?.email,
        creatorSub: act?.sub,
      };
    }
    ```
  </Tab>

  <Tab title="Python (PyJWT)">
    ```python theme={null}
    import jwt
    from jwt import PyJWKClient

    JWKS_URL = "https://api.anthropic.com/v1/code/.well-known/jwks.json"
    PREFIX = "sk-ant-cc-"
    EXPECTED_POOL_ID = "ccpool_..."

    jwks = PyJWKClient(JWKS_URL)


    def verify_session_token(raw: str) -> dict:
        if not raw.startswith(PREFIX):
            raise ValueError("not a self-hosted runner session token")
        token = raw.removeprefix(PREFIX)

        signing_key = jwks.get_signing_key_from_jwt(token)
        payload = jwt.decode(
            token,
            signing_key.key,
            algorithms=["ES256"],
            issuer="ccr",
            audience=EXPECTED_POOL_ID,
        )

        if payload.get("ccr:role") != "session_worker":
            raise ValueError("token is not a session_worker token")

        act = payload.get("act") or {}
        return {
            "session_id": payload["ccr:session_id"],
            "pool_id": payload["ccr:pool_id"],
            "org_id": payload["ccr:org_id"],
            "creator_email": act.get("email"),
            "creator_sub": act.get("sub"),
        }
    ```
  </Tab>
</Tabs>

<h3 id="verify-the-token-inside-the-session">
  Проверка токена внутри сеанса
</h3>

[Скрипты-обертки](/docs/ru/self-hosted-environments-configuration#wrapper-scripts) работают внутри сеанса, перед запуском Claude. Вместо вызова библиотеки JWT они могут запустить подкоманду `self-hosted-runner decode-token` бинарного файла runner. Подкоманда читает токен из позиционного аргумента, из `CLAUDE_CODE_SESSION_ACCESS_TOKEN` или из перенаправленного stdin в этом порядке, затем удаляет префикс, проверяет подпись против конечной точки JWKS, проверяет срок действия и выводит утверждения как JSON. Подкоманда выполняет только проверки подписи и срока действия; она не проверяет `iss`, `aud` или `ccr:role`. Когда решение об аутентификации вашей обертки зависит от этих утверждений, прочитайте их из выведенного JSON и сравните их явно.

Эта команда извлекает идентификацию создателя, предпочитая субъект поставщика SSO, затем адрес электронной почты, затем субъект `act.sub` создателя, `user:<id>` или `agent:<id>`:

```bash theme={null}
"$CLAUDE_RUNNER_CLAUDE_BIN" self-hosted-runner decode-token | jq -re '.act.attested_by.sub // .act.email // .act.sub'
```

Обертки получают абсолютный путь к собственному бинарному файлу runner в `CLAUDE_RUNNER_CLAUDE_BIN`; используйте этот путь вместо разрешенного PATH `claude`, чтобы декодирование выполнялось на том же бинарном файле, который использует сам runner.

Используйте `jq -re` вместо `jq -r`, чтобы отсутствующее утверждение вызвало ненулевой выход. С одним `-r`, отсутствующее утверждение выводит буквальную строку `null` и выходит с нулем, что молча передает плохое значение вниз по потоку. Передайте `--no-verify` в `decode-token` только для автономной проверки, где конечная точка JWKS недоступна.

<h2 id="claims-reference">
  Справочник утверждений
</h2>

Таблица ниже перечисляет утверждения токена сеанса, релевантные для проверки. Читайте идентификацию из пространства имен `ccr:*` и цепи `act`; плоские утверждения `account_email`, `organization_uuid` и `account_uuid` — это дубликаты обратной совместимости, которые могут быть удалены. Сеансы, которые создает идентификация сервиса вашей организации, включая сеансы канала Claude Tag, содержат субъект `agent:` в `act.sub` и опускают `act.email`, `ccr:account_id`, `account_email` и `account_uuid`. Два утверждения электронной почты также опциональны для сеансов, созданных пользователем: Anthropic записывает их при создании сеанса только когда учетные данные создающего запроса содержат электронную почту, и сеанс, отправленный из CLI, может не иметь обоих, поэтому ключевая идентификация на `act.sub` или `ccr:account_id` вместо электронной почты. Токены также могут содержать дополнительные утверждения помимо этой таблицы; игнорируйте утверждения, которые вы не узнаете.

| Утверждение         | Тип              | Описание                                                                                                                                                                                                                                                                                                                                                                                                           |
| :------------------ | :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss`               | string           | Всегда `ccr`.                                                                                                                                                                                                                                                                                                                                                                                                      |
| `sub`               | string           | `ccr:session:<session_id>`.                                                                                                                                                                                                                                                                                                                                                                                        |
| `aud`               | array of strings | Всегда содержит `anthropic-api`. Для сеансов в самостоятельно размещаемых окружениях массив также содержит ваш ID окружения, такой как `ccpool_...`. Проверьте ID окружения, а не `anthropic-api`.                                                                                                                                                                                                                 |
| `exp`               | number           | Срок действия как временная метка Unix. Четырехчасовой срок действия по умолчанию, максимум восемь часов.                                                                                                                                                                                                                                                                                                          |
| `iat`               | number           | Выданный как временная метка Unix.                                                                                                                                                                                                                                                                                                                                                                                 |
| `jti`               | string           | Уникальный идентификатор токена.                                                                                                                                                                                                                                                                                                                                                                                   |
| `ccr:role`          | string           | Всегда `session_worker` для токенов сеанса.                                                                                                                                                                                                                                                                                                                                                                        |
| `ccr:session_id`    | string           | ID сеанса. То же значение, что и суффикс `sub`.                                                                                                                                                                                                                                                                                                                                                                    |
| `ccr:pool_id`       | string           | Ваш ID окружения. То же значение, которое отображается в `aud`.                                                                                                                                                                                                                                                                                                                                                    |
| `ccr:org_id`        | string           | Ваш ID организации Anthropic.                                                                                                                                                                                                                                                                                                                                                                                      |
| `ccr:account_id`    | string           | ID учетной записи Anthropic создающего пользователя: значение `act.sub` без префикса `user:`, помеченный ID `user_...`. То же значение, которое несет `CLAUDE_RUNNER_ACCOUNT_ID` [хука spawn-runner](/docs/ru/self-hosted-environments-configuration#the-spawn-runner-hook) и принимает [`--lock-to-account`](/docs/ru/self-hosted-environments-reference#runner-cli-flags), поэтому все три сравниваются как равные строки. |
| `account_email`     | string           | Дубликат `act.email`; отсутствует всякий раз, когда отсутствует `act.email`.                                                                                                                                                                                                                                                                                                                                       |
| `organization_uuid` | string           | Ваш UUID организации Anthropic.                                                                                                                                                                                                                                                                                                                                                                                    |
| `account_uuid`      | string           | UUID учетной записи Anthropic создающего пользователя.                                                                                                                                                                                                                                                                                                                                                             |
| `act`               | object           | Цепь делегирования [RFC 8693](https://www.rfc-editor.org/rfc/rfc8693). См. [Цепь `act`](#the-act-chain).                                                                                                                                                                                                                                                                                                           |

<h3 id="the-act-chain">
  Цепь `act`
</h3>

Утверждение `act` записывает полный путь делегирования от идентификации пользователя или сервиса, который создал сеанс, вниз к [окружению](/docs/ru/self-hosted-environments#key-concepts), чей секрет допустил runner, и идентификации, которая создала этот секрет. Создатель — это самый внешний актор, поэтому `act.sub` идентифицирует его напрямую.

| Путь              | Описание                                                                                                                                                                                                                                                                                             |
| :---------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `act.sub`         | ID пользователя Anthropic создающего пользователя в форме `user:<id>` или `agent:<id>`, когда идентификация сервиса вашей организации создала сеанс, как это происходит для сеансов канала Claude Tag.                                                                                               |
| `act.email`       | Адрес электронной почты создающего пользователя, когда он был записан при создании сеанса. Не требуйте его; ключевая идентификация на `act.sub`.                                                                                                                                                     |
| `act.attested_by` | Аттестация поставщика идентификации вышестоящего уровня для создающего пользователя, когда доступна. `act.attested_by.sub` — это субъект, выданный вашим поставщиком SSO, таким как Google или Okta. Предпочитайте это `act.email` при сопоставлении с идентификациями в ваших собственных системах. |
| `act.act`         | Runner, который запустил сеанс. `act.act.sub` — это `ccr:runner:<runner_id>`.                                                                                                                                                                                                                        |
| `act.act.act`     | Окружение. `act.act.act.sub` — это `ccr:pool:<pool_id>`.                                                                                                                                                                                                                                             |
| `act.act.act.act` | Идентификация, которая создала секрет окружения, с которым runner зарегистрировался. Цепь заканчивается здесь.                                                                                                                                                                                       |

<h2 id="scope-derived-credentials">
  Ограничение полученных учетных данных
</h2>

Токен сеанса идентифицирует пользователя или идентификацию сервиса, который создал сеанс, но не рассматривайте его как эквивалент этого создателя, входящего напрямую. Токен находится в переменной окружения внутри сеанса, поэтому любой код, который запускает Claude, и любой инструмент или MCP сервер, который запускает сеанс, могут его прочитать и представить.

Проверка также автономна: токен, который проверяется против JWKS, остается действительным до его `exp`, независимо от того, что произошло с сеансом с тех пор, и Anthropic не публикует канал отзыва для токенов сеанса. Привяжите все, что вы получаете из токена, соответственно.

Когда ваш сервис обменивает токен на внутренние учетные данные, выдайте учетные данные, ограниченные тем, что один сеанс кодирования должен достичь:

* **Ограничьте возможности**: предоставьте доступ на чтение и запись к ресурсам, которые сеансу нужны для задач кодирования, а не административные возможности, которые создатель имеет в другом месте.
* **Ограничьте время жизни**: привяжите полученные учетные данные к `exp` токена или короче.
* **Аудит как сеанс**: запишите `ccr:session_id` и `jti` рядом с идентификацией создателя, чтобы вы могли отследить действия обратно к конкретному сеансу.

<h2 id="related-environment-variables">
  Связанные переменные окружения
</h2>

Идентификация создателя также отображается в простых переменных окружения на двух поверхностях, которые никогда не проверяют токен:

* **[Хук `spawn-runner`](/docs/ru/self-hosted-environments-configuration#the-spawn-runner-hook), на оркестраторе**: хук работает перед тем, как для поставленного в очередь сеанса существует какой-либо runner, и получает идентификацию создателя в переменных, таких как `CLAUDE_RUNNER_ACCOUNT_EMAIL` и `CLAUDE_RUNNER_ACCOUNT_ID`. Оркестратор читает их из рабочего заказа, подписанного одноразового токена, который авторизует запуск одного runner, без проверки подписи самого рабочего заказа; утверждения доверяются, потому что рабочий заказ поступает через соединение оркестратора с Anthropic, которое аутентифицирует секрет окружения.
* **[Скрипты-обертки](/docs/ru/self-hosted-environments-configuration#wrapper-scripts), внутри сеанса**: обертки получают `CCR_SESSION_ACCOUNT_EMAIL`, адрес электронной почты создателя, предварительно извлеченный из токена без проверки подписи. Переменная подходит для маркировки, такой как трейлеры коммитов, а не для решений об аутентификации.

Используйте простые переменные для решений на стороне оркестратора, таких как выбор образа машины. Используйте `CLAUDE_CODE_SESSION_ACCESS_TOKEN`, когда нижестоящему сервису нужно независимое криптографическое доказательство вместо доверия окружению runner.

<h2 id="what’s-next">
  Что дальше
</h2>

* [Самостоятельно размещаемые окружения](/docs/ru/self-hosted-environments): окружение, runner и модель сеанса; [краткое руководство](/docs/ru/self-hosted-environments-quickstart) и [Deploy to production](/docs/ru/self-hosted-environments-deploy) содержат настройку и операции
* [Настройка сеансов](/docs/ru/self-hosted-environments-configuration): скрипты-обертки, которые потребляют токен, и хук `spawn-runner`
* [Справочник](/docs/ru/self-hosted-environments-reference): флаги CLI, переменные окружения и метрики
