env-master
ENСоздать аккаунт
Разделы документации

Справочник API

Полный справочник пользовательского REST API — в репозитории: docs/API.md. Здесь — то, что нужно знать до первого запроса.

База и формат

Все пути относительно /api/v1, формат JSON. Ответы и коды ошибок на английском; язык интерфейса — забота клиента. Живость сервера — GET /healthz (вне /api/v1).

Аутентификация

СубъектМеханизм
ЧеловекAuthorization: Bearer <access-токен>, 15 минут
Браузертот же заголовок + refresh в httpOnly-cookie
Identityсвой токен из /machine/login или /machine/enroll, скоуп «проект × окружение», TTL настраивается от 60 до 86400 с

Заголовок X-Client (web, portal, cli, sdk, mobile) попадает в аудит и решает, где окажется refresh-токен: браузеру он выдаётся только в cookie.

Машинные маршруты:

МаршрутЧто делает
POST /machine/loginclient ID + client secret → access-токен
POST /machine/enrollenrollment-токен + публичный ключ → постоянные учётные данные
GET /machine/entries?project=&env=записи окружения в скоупе identity
POST /machine/heartbeatотметка «жив» в lastUsedAt identity

Оба подробно разобраны на странице Сервисы и identity.

Ошибки

{ "error": { "code": "VALIDATION", "message": "..." } }

Ветвиться следует по code, а не по тексту. Каждый ответ несёт X-Request-Id — это единственное, что нужно процитировать в обращении.

HTTPКодКогда на деле
400VALIDATIONтело или параметры не прошли проверку; текст говорит, что именно
401UNAUTHENTICATEDнет токена, токен не тот, неверные client ID / client secret, неизвестный enrollment-токен
401TOKEN_EXPIREDaccess-токен протух; войдите заново
402QUOTA_EXCEEDEDупёрлись в лимит тарифа — дело не в правах
403FORBIDDENроли не хватает, IP вне allowedCidrs, скоуп identity не тот
403IDENTITY_REVOKEDidentity отозвана; токены по ней не принимаются
403ENROLLMENT_EXPIREDenrollment-токену больше 10 минут, им не воспользовались
403ENROLLMENT_USEDenrollment-токен уже использован — тревога, см. identity
403ORG_BLOCKEDорганизация заблокирована оператором
404NOT_FOUNDнет такого ресурса (или нет прав его видеть)
409CONFLICTslug занят, identity уже отозвана, откатывать нечего
413PAYLOAD_TOO_LARGEтело запроса больше лимита (по умолчанию 1 МиБ)
429RATE_LIMITEDслишком часто; ждите Retry-After
500INTERNALошибка на стороне сервера; в обращении укажите X-Request-Id

Лимиты по частоте — на странице Безопасность.

Пагинация

{ "items": [...], "nextCursor": "..." }. Курсор непрозрачный: передайте его обратно в ?cursor=, пока он приходит.

Ротация

Политика вешается на запись; прогоны идут по расписанию фоновым воркером или запускаются вне очереди. Фазы, стратегии и метки pending/current разобраны на странице Ротация секретов.

МетодПутьРоль
PUT/entries/:id/rotation-policyadmin проекта
GET/entries/:id/rotation-policyviewer проекта
DELETE/entries/:id/rotation-policyadmin проекта
POST/rotation-policies/:id/run-nowadmin проекта
GET/rotation-runs?policyId=<id>viewer проекта
GET/orgs/:id/rotationsучастник организации

Тело PUT:

{
  "rotator": "postgres",
  "strategy": "dual-credential",
  "intervalSeconds": 604800,
  "config": {
    "adminDsnEntryRef": "my-org/billing-api/production/DB_ADMIN_DSN",
    "usernames": ["app_a", "app_b"]
  },
  "enabled": true
}
  • rotator — сейчас только postgres;
  • strategy — dual-credential или single-user;
  • intervalSeconds — целое, не меньше 60;
  • config — разбирает ротатор; ссылки на секреты в нём должны лежать в той же организации, иначе VALIDATION, а на проект каждой из них у вас должна быть роль не ниже member, иначе FORBIDDEN. PUT заменяет config целиком: при правке пересылайте activeUsername из GET, иначе ротатор начнёт с первого пользователя в списке;
  • enabled — необязательный, по умолчанию true.

PUT создаёт политику или заменяет существующую и возвращает её: { id, entryId, rotator, strategy, intervalSeconds, config, enabled, nextRotationAt, createdAt }. GET возвращает политику записи, DELETE — 204; если политики нет, оба отвечают NOT_FOUND.

POST /rotation-policies/:id/run-now запускает прогон немедленно и возвращает его. Если прогон этой политики уже идёт, ответ — 409 CONFLICT: ручной запуск и фоновый воркер делят одну аренду политики. Приостановленная (enabled: false) политика run-now выполняется — это явная воля, а не расписание; каждый такой запуск пишется в журнал событием rotation.run.requested. GET /rotation-runs?policyId=<id> — { items } с последними прогонами политики (до 50, новые первыми). Прогон: { id, policyId, phase, status, error?, resultVersion?, startedAt, completedAt? }, где phase — одна из create, set, test, finish, а status — running, testing, succeeded или failed; текст error есть только у failed, а resultVersion — номер версии записи, которую создал прогон (есть, когда прогон дошёл до записи значения).

GET /orgs/:id/rotations — сводка по организации: до 5 последних прогонов на политику, всего до 50, по проектам, где у вас есть роль (владелец и администратор организации видят все проекты). В каждом элементе дополнительно entryKey — имя ключа записи.

Частая ошибка

GET /projects требует ?orgId= — без него ответ будет VALIDATION.