API управления

Области доступа

Полный список scopes, что даёт каждая, правило «право на запись включает чтение» и запрет выдавать больше, чем есть у себя.

На этой странице · 7

Области доступа (scopes) ограничивают серверный ключ. Ключ с пустым списком — полный доступ; так работают все ключи, выданные до появления областей, и так же выглядит «ключ для себя». Ограниченный ключ обязан перечислить области явно.

Полный список

Список живёт в apps/api/src/lib/mgmt.ts и целиком отдаётся в GET /api/v1/meta и в поле x-scopes спецификации OpenAPI.

Области доступа

ОбластьЧто даёт
*полный доступ
account:readпрофиль и сводка аккаунта
account:writeизменение профиля, пароля, сессий
sandboxes:readсписок и настройки песочниц
sandboxes:writeсоздание, изменение, сброс песочниц
keys:readсписок ключей
keys:writeвыпуск, ротация и отзыв ключей
webhooks:readподписки и журнал доставок
webhooks:writeсоздание подписок и тестовые отправки
scenarios:readсценарии симуляции
scenarios:writeсоздание и запуск сценариев
bursts:readсостояние серий событий
bursts:writeзапуск и остановка серий событий
mocks:readсвои моки
mocks:writeсоздание и изменение своих моков
logs:readжурнал запросов
logs:writeочистка журнала запросов
catalog:readкаталог методов и сервисов
apps:readлокальные приложения Bitrix24 и их токены
apps:writeсоздание, установка и удаление приложений
console:writeвызов методов через консоль
tunnel:readсостояние туннелей CLI

Право на запись включает чтение

Проверка устроена так: область считается выданной, если она перечислена явно, если выдана *, если список пуст — или если запрошено чтение ресурса, на запись которого право есть. Возможность изменить вебхук без возможности его прочитать не имеет смысла, а держать в ключе обе строки — лишний повод ошибиться.

То есть webhooks:write даёт и webhooks:read. Обратное неверно.

Какая область нужна маршруту

Область каждого маршрута указана в его описании в спецификации OpenAPI — строкой «Требуемая область доступа». Сводно:

Маршруты по областям

ОбластьМаршруты
account:readGET /account, GET /account/sessions
account:writePATCH /account, DELETE /account, POST /account/password, DELETE /account/sessions/{id}, POST /account/sessions/revoke-all
sandboxes:readGET /sandboxes, GET /sandboxes/{sandboxId}
sandboxes:writePOST /sandboxes, PATCH /sandboxes/{sandboxId}, DELETE /sandboxes/{sandboxId}, POST /sandboxes/{sandboxId}/reset
keys:readGET /keys, GET /keys/{id}
keys:writePOST /keys, PATCH /keys/{id}, DELETE /keys/{id}, POST /keys/{id}/revoke, POST /keys/{id}/rotate
webhooks:readGET /webhooks, GET /webhooks/{id}, GET /webhooks/{id}/deliveries, GET /deliveries/{id}
webhooks:writePOST /webhooks, PATCH /webhooks/{id}, DELETE /webhooks/{id}, POST /webhooks/{id}/test, POST /webhooks/retry-failed, POST /deliveries/{id}/retry
scenarios:readGET /scenarios, GET /scenarios/{id}
scenarios:writePOST /scenarios, PATCH /scenarios/{id}, DELETE /scenarios/{id}, POST /scenarios/{id}/run
bursts:readGET /bursts, GET /bursts/{id}
bursts:writePOST /bursts, POST /bursts/{id}/stop
mocks:readGET /mocks, GET /mocks/{id}, POST /mocks/preview
mocks:writePOST /mocks, PATCH /mocks/{id}, DELETE /mocks/{id}, POST /mocks/{id}/enable, POST /mocks/{id}/disable, POST /mocks/import
logs:readGET /logs, GET /logs/{id}, GET /logs/export, GET /usage, GET /alerts
logs:writePOST /logs/clear, POST /alerts/{id}/read
catalog:readGET /services, GET /methods, GET /methods/{id}, GET /events
apps:readGET /apps, GET /apps/{id}
apps:writePOST /apps, PATCH /apps/{id}, DELETE /apps/{id}
console:writePOST /console/execute
tunnel:readGET /tunnel/status

Сводка и уведомления живут в области журнала

GET /usage и GET /alerts требуют logs:read, а не account:read: и то и другое считается по журналу запросов. Пометка уведомления прочитанным — это запись, поэтому POST /alerts/{id}/read требует logs:write.

Отказ 403

Если области нет, ответ приходит до выполнения запроса и перечисляет выданное:

curl -s "$STEND/api/v1/keys" -H "Authorization: Bearer $LIMITED_KEY"
{
  "error": "FORBIDDEN",
  "message": "Ключу не выдана область доступа «keys:read» (список ключей). Выданы: logs:read, sandboxes:read"
}

Нельзя выдать больше, чем имеешь

Ключ не может выпустить, изменить или прокрутить ключ шире себя. Иначе один keys:write превращался бы в полный доступ за два запроса.

  1. 1

    Ключ с ограниченными правами выпускает более узкий ключ

    Это разрешено: logs:read у выдающего есть.

    curl -s -X POST "$STEND/api/v1/keys" \
      -H "Authorization: Bearer $LIMITED_KEY" -H 'Content-Type: application/json' \
      -d '{"name":"doc-narrow","services":["bitrix24"],"kind":"server","scopes":["logs:read"]}'
    
  2. 2

    Тот же ключ пробует выдать область, которой у него нет

    {
      "error": "FORBIDDEN",
      "message": "Нельзя выдать области «account:write»: их нет у вызывающего ключа. Выданы: «keys:write», «logs:read»"
    }
    
  3. 3

    И пробует выпустить ключ вообще без списка областей

    Пустой список — это полный доступ, поэтому такой запрос тоже отклоняется.

    {
      "error": "FORBIDDEN",
      "message": "Ключ без списка scopes получает полный доступ, а у вызывающего ключа доступ ограничен. Перечислите области явно, не шире выданных: «keys:write», «logs:read»"
    }
    

То же правило работает в трёх местах:

  • POST /keys — выпуск нового ключа;
  • PATCH /keys/{id} — правка областей: собственному ключу можно только урезать права, а не добавить;
  • POST /keys/{id}/rotate — ротация выдаёт на руки рабочий секрет, поэтому прокрутить можно только ключ не шире собственных прав. Иначе ключ с одним keys:write прокручивал бы ключ с полным доступом и получал его права.

Ключу песочницы области не назначаются

Ключ stend_sbx_… в Management API не принимается, поэтому его области ни на что не влияли бы, а в списке показывали бы права, которых нет. Запрос отклоняется:

{
  "error": "UNPROCESSABLE",
  "message": "Области доступа задаются только серверному ключу: ключом песочницы Management API не пользуются, его scopes ни на что не влияют. Уберите scopes или укажите kind=server"
}

Код ответа — 422.

Подводные камни

  • Урезание прав действует немедленно: правка scopes сбрасывает кеш разбора ключей. Ждать полминуты, как было бы без сброса, не нужно.
  • Признак fullAccess в карточке ключа — готовый ответ на вопрос «это ключ без ограничений?»: он равен true у серверного ключа с пустым списком или с *.
  • У cookie-сессии областей нет — всегда полный доступ. Проверять ограничения ключа через браузер бессмысленно.