Внешний API (v3)
Панель отдаёт HTTP API для сторонних интеграций на /api/v3/*. Авторизация — по ключу, права — по областям доступа (scopes).
Включение
API выключен по умолчанию. Включается переменными веб-бэкенда:
| Переменная | По умолчанию | Что делает |
|---|---|---|
EXTERNAL_API_ENABLED | false | главный выключатель /api/v3/* |
EXTERNAL_API_DOCS | false | отдавать Swagger UI на /api/v3/docs |
Текущее состояние видно в интерфейсе: Настройки → API.
Создание ключа
- API и вебхуки → API-ключи
- Создать ключ, указать:
- имя — понятное человеку, например
prod-monitoring - срок жизни — бессрочно, 1, 7, 30, 90 или 365 дней; просроченный ключ отвечает
401 - области доступа — см. таблицу ниже
- описание — по желанию
- имя — понятное человеку, например
- Ключ показывается один раз. Скопируйте его в своё хранилище секретов: закрыть диалог, не подтвердив сохранение, панель не даст
- Дальше виден только префикс — первые 12 символов вида
rwa_AbCd3fGh. Полное значение восстановить нельзя: если потеряли, ключ придётся перевыпустить
Формат
rwa_<43 символа urlsafe base64>Префикс rwa_ помечает класс ключа, дальше 32 случайных байта. В базе хранится только SHA-256 от ключа — открытого значения у сервера нет.
Авторизация
Ключ передаётся заголовком X-API-Key в каждом запросе:
curl -H "X-API-Key: rwa_ВАШ_КЛЮЧ" https://admin.example.com/api/v3/usersimport requests
r = requests.get(
"https://admin.example.com/api/v3/users",
headers={"X-API-Key": "rwa_ВАШ_КЛЮЧ"},
timeout=10,
)const res = await fetch("https://admin.example.com/api/v3/users", {
headers: { "X-API-Key": "rwa_ВАШ_КЛЮЧ" },
})Что вернётся при отказе:
| Ситуация | Ответ |
|---|---|
| нет заголовка | 401 Missing X-API-Key header |
| ключ неверный, отключён или просрочен | 401 Invalid or expired API key |
| ключу не хватает области доступа | 403 Missing scope: <имя> |
| превышен лимит запросов | 429 с заголовком Retry-After |
Области доступа
Запрос проходит, только если у ключа есть область, которую требует эндпоинт.
| Область | Что разрешает | Примеры |
|---|---|---|
users:read | читать пользователей | GET /users, GET /users/{uuid} |
users:write | создавать, менять, включать, сбрасывать трафик | POST /users, POST /users/{uuid}/enable |
users:delete | удалять пользователя | DELETE /users/{uuid} |
nodes:read | читать ноды | GET /nodes, GET /nodes/{uuid} |
nodes:write | включать, отключать, перезапускать ноду, синхронизировать список нод с панелью | POST /nodes/{uuid}/restart |
nodes:token | генерировать и отзывать токен агента ноды | POST /nodes/{uuid}/agent-token/generate |
hosts:read | читать хосты | GET /hosts |
stats:read | общая статистика | GET /stats |
violations:read | читать нарушения | GET /violations |
enforcement:support | сообщать об обращении клиента во внешнюю поддержку | POST /support-events |
bulk:write | массовые операции | POST /users/bulk/* |
Разумные привычки:
- Давайте ровно то, что нужно: дашборду хватит
users:read,users:deleteему ни к чему - Свой ключ на каждую интеграцию — тогда его отзыв не заденет остальные
- Ключам CI/CD ставьте короткий срок жизни и перевыпускайте регулярно
bulk:writeобходит проверки по отдельным пользователям — относитесь к нему как к привилегированномуnodes:tokenдаёт доступ к токену агента — этим токеном аутентифицируется Collector API, WebSocket агента и удалённый терминал, то есть фактически это ключ к хосту ноды. Ещё более привилегированная область, чемbulk:write
Ключ не может получить область, права на которую нет у создавшего его админа. Области, которые работают по всем юзерам (users:*, bulk:write, violations:read, enforcement:support), выдаёт только админ без ограничения видимости юзеров. Ключ отключённого или удалённого админа перестаёт работать.
Ограничения ключа
Кроме областей, ключ можно сузить — в окне создания или правки:
- Адреса — список IP и подсетей, например
203.0.113.10и10.0.0.0/24. С любого другого адреса ключ считается недействительным и получает401. Пустой список — любой адрес - Юзеры — сквады и тег. Ключ видит и меняет только юзеров, которые состоят хотя бы в одном из этих сквадов и носят этот тег (если заданы оба условия, нужны оба), и только их нарушения. Создать юзера такой ключ может лишь в своих сквадах и со своим тегом — тег подставляется сам
Журнал запросов
У каждого ключа в интерфейсе есть журнал последних запросов: метод, путь, код ответа, IP и время. По нему видно, кто и откуда ходит с ключом, — и что пора его перевыпустить.
Лимиты запросов
Считаются в окне 60 секунд, отдельно по каждому ключу.
| Переменная | По умолчанию | На что действует |
|---|---|---|
API_V3_RATE_READ_PER_MIN | 120 | запросы GET |
API_V3_RATE_WRITE_PER_MIN | 60 | POST, PATCH, DELETE кроме массовых |
API_V3_RATE_BULK_PER_MIN | 10 | всё под /users/bulk/ |
При превышении приходит 429 и заголовок Retry-After с числом секунд до конца окна.
Счётчик привязан к ключу, а не к адресу: два разных ключа с одного сервера квоту не делят.
Перевыпуск
- Кнопка Перевыпустить рядом с ключом
- Выберите, сколько ещё будет работать старое значение: сразу погасить — если ключ утёк, или оставить на 1–72 часа, пока интеграция переключается на новый
- Новое значение показывается один раз — обновите интеграцию
Имя, области доступа, ограничения, срок и описание сохраняются — история не теряется. Перевыпуск попадает в аудит-лог.
Просроченные ключи
По достижении срока ключ считается недействительным, в списке появляется отметка. Оживить его можно только перевыпуском — новый секрет, новый отсчёт.
Аудит
Создание, изменение, перевыпуск и удаление ключей пишутся в аудит-лог: кто, с какого адреса, что именно поменял. Сам секрет туда, разумеется, не попадает.
Частые вопросы
Почему «последнее использование» отстаёт? Отметка сбрасывается в базу раз в 30 секунд — иначе под нагрузкой строка ключа стала бы точкой блокировок.
Можно один ключ на несколько интеграций? Технически да, практически нет: одна скомпрометированная система утаскивает за собой остальные, а по аудиту потом не понять, кто что делал.
Можно посмотреть ключ ещё раз? Нет. Только перевыпуск.
Есть ограничение по адресам? Да — список IP и подсетей в ограничениях ключа.