API управления
Области доступа
Полный список scopes, что даёт каждая, правило «право на запись включает чтение» и запрет выдавать больше, чем есть у себя.
На этой странице · 7
Области доступа (scopes) ограничивают серверный ключ. Ключ с пустым списком — полный доступ; так работают все ключи, выданные до появления областей, и так же выглядит «ключ для себя». Ограниченный ключ обязан перечислить области явно.
Полный список
Список живёт в apps/api/src/lib/mgmt.ts и целиком отдаётся в GET /api/v1/meta
и в поле x-scopes спецификации OpenAPI.
Области доступа
Право на запись включает чтение
Проверка устроена так: область считается выданной, если она перечислена явно,
если выдана *, если список пуст — или если запрошено чтение ресурса, на запись
которого право есть. Возможность изменить вебхук без возможности его прочитать
не имеет смысла, а держать в ключе обе строки — лишний повод ошибиться.
То есть webhooks:write даёт и webhooks:read. Обратное неверно.
Какая область нужна маршруту
Область каждого маршрута указана в его описании в спецификации OpenAPI — строкой «Требуемая область доступа». Сводно:
Маршруты по областям
Сводка и уведомления живут в области журнала
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
Ключ с ограниченными правами выпускает более узкий ключ
Это разрешено:
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
Тот же ключ пробует выдать область, которой у него нет
{ "error": "FORBIDDEN", "message": "Нельзя выдать области «account:write»: их нет у вызывающего ключа. Выданы: «keys:write», «logs:read»" } - 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-сессии областей нет — всегда полный доступ. Проверять ограничения ключа через браузер бессмысленно.