Эндпоинты сервиса iams-v2
Документ описывает все HTTP-эндпоинты, которые предоставляет сервис iams (IAM: пользователи, ресурсы/проекты, права доступа). В отличие от фронтенд-модулей, здесь описан контракт самого сервиса.
Как устроено взаимодействие
Сервер — Fiber (internal/controller/http/server.go). Маршруты регистрируются двумя наборами:
- Внутренний контур (
RegisterAPIRoutes) — без аутентификации на уровне приложения, доступ ограничивается сетевым слоем (не публикуется через ingress). Базовые группы: /api/v0, /api/admin/v0, /api/v1, /api/v2.
- Внешний контур (
RegisterExternalAPIRoutes) — регистрируется только при AUTH_ENABLED=true. Перед маршрутами выполняется разбор JWT (AuthMiddleware) и пометка контекста (ExternalAPIMiddleware, для админ-группы дополнительно ExternalUserAdminAPIMiddleware). Базовые группы: /external/api/v0, /external/api/admin/v0, /external/api/v1, /external/api/v2. Внешний контур публикует подмножество внутренних маршрутов, часть — только на чтение.
Глобальные middleware: requestid, recover, OTel (при OTEL_ENABLED и заданном OTEL_SERVICE_NAME), логирование.
Аутентификация (внешний контур)
Токен передаётся заголовком Authorization: Bearer <jwt> (internal/controller/http/jwt/parser.go). Подпись токена не проверяется — доверие делегируется вышестоящему gateway/virtual service. Схема разбора выбирается по заголовку Identity:
- заголовок
Identity отсутствует/пуст → legacy-формат (Django SimpleJWT);
- заголовок
Identity задан → Zitadel (клейм urn:zitadel:iam:user:metadata, значения полей — base64).
Формат ответов и ошибок
Успешные ответы — JSON (списки: { count, results }; часть эндпоинтов возвращает объект напрямую). Ошибки — JSON { "error": "...", "id": "..." } (httpx.Response). Доменный Kind маппится на HTTP-статус (httpx/error_resolve.go): InvalidArgument/OutOfRange→400, Unauthenticated→401, PermissionDenied→403, NotFound→404, Aborted/AlreadyExists→409, PreconditionFailed→412, ResourceExhausted→429, Unavailable→503, Internal/Unknown/DataLoss→500. Идентификатор запроса — заголовок из requestid.
Пагинация и фильтры
Списки — через query limit/offset (по умолчанию limit=1000). Дополнительные фильтры задаются query-параметрами (напр. для /resource: parent_id, type, tenant_id, name, code, public_id, target_id, service_accounts; для /users: username, search, is_active, is_staff, is_superuser, service_account_id, id, company_id, departments, positions, groups).
Служебные эндпоинты
| Метод |
Путь |
Назначение |
| GET |
/api/health |
Health-check: проверка БД и (при включении) Kafka. 200 — ok, 503 — недоступность зависимости |
Внутренний контур
Users (/api/v0/users, /api/admin/v0, /api/v1)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/users |
Список пользователей (фильтры, пагинация) |
| POST |
/api/v0/users |
Создать пользователя (если включён use case) |
| PATCH |
/api/v0/users |
Массовое обновление пользователей (legacy bulk_update) |
| GET |
/api/v0/users/:id |
Пользователь по id |
| PUT |
/api/v0/users/:id |
Полное обновление пользователя |
| PATCH |
/api/v0/users/:id |
Частичное обновление пользователя |
| DELETE |
/api/v0/users/:id |
Удалить пользователя |
| POST |
/api/admin/v0/users/activation |
Активация/деактивация пользователей компании |
| POST |
/api/v1/users-with-resources |
Пользователи с их ресурсами (тело: tenant_id, id[]) |
| GET |
/api/v1/users-grouped-by-resource/ |
Пользователи, сгруппированные по ресурсу (если включён use case) |
Permission check (/api/v0)
| Метод |
Путь |
Назначение |
| POST |
/api/v0/permissions-check |
Проверка набора прав пользователя (user_id, checks[]) |
Groups (/api/v0/groups)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/groups |
Список групп |
| POST |
/api/v0/groups |
Создать группу |
| POST |
/api/v0/groups/search |
Поиск групп (пагинация, сортировка, фильтры) |
| GET |
/api/v0/groups/:id |
Группа по id |
| PUT |
/api/v0/groups/:id |
Обновить группу |
| PATCH |
/api/v0/groups/:id |
Частично обновить группу |
| DELETE |
/api/v0/groups/:id |
Удалить группу |
Positions (/api/v0/positions)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/positions |
Список должностей |
| POST |
/api/v0/positions |
Создать должность |
| GET |
/api/v0/positions/:id |
Должность по id |
| PUT |
/api/v0/positions/:id |
Обновить должность |
| PATCH |
/api/v0/positions/:id |
Частично обновить должность |
| DELETE |
/api/v0/positions/:id |
Удалить должность |
Departments (/api/v0/departments)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/departments |
Список подразделений |
| POST |
/api/v0/departments |
Создать подразделение |
| GET |
/api/v0/departments/:id |
Подразделение по id |
| PUT |
/api/v0/departments/:id |
Обновить подразделение |
| PATCH |
/api/v0/departments/:id |
Частично обновить подразделение |
| DELETE |
/api/v0/departments/:id |
Удалить подразделение |
Django permissions (/api/v0/permissions)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/permissions |
Список permission'ов |
| POST |
/api/v0/permissions |
Создать permission |
| POST |
/api/v0/permissions/search |
Поиск permission'ов |
| GET |
/api/v0/permissions/:id |
Permission по id |
| DELETE |
/api/v0/permissions/:id |
Удалить permission |
Resource types v0 (/api/v0/resource-types)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/resource-types |
Список типов ресурсов |
| POST |
/api/v0/resource-types |
Создать тип |
| GET |
/api/v0/resource-types/:id |
Тип по id |
| PUT |
/api/v0/resource-types/:id |
Обновить тип |
| PATCH |
/api/v0/resource-types/:id |
Частично обновить тип |
| DELETE |
/api/v0/resource-types/:id |
Удалить тип |
Resources v0 (/api/v0/resources)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/resources |
Список ресурсов (legacy v0) |
| POST |
/api/v0/resources |
Создать ресурс |
| GET |
/api/v0/resources/:id |
Ресурс по id |
| PUT |
/api/v0/resources/:id |
Обновить ресурс |
| PATCH |
/api/v0/resources/:id |
Частично обновить ресурс |
| DELETE |
/api/v0/resources/:id |
Удалить ресурс |
Projects v0 (/api/v0/projects)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/projects |
Список проектов |
| POST |
/api/v0/projects |
Создать проект |
| GET |
/api/v0/projects/:publicID |
Проект по public id |
| PUT |
/api/v0/projects/:publicID |
Обновить проект |
| PATCH |
/api/v0/projects/:publicID |
Частично обновить проект |
| DELETE |
/api/v0/projects/:publicID |
Удалить проект |
Widgets v0 (/api/v0/widgets)
| Метод |
Путь |
Назначение |
| GET |
/api/v0/widgets |
Список виджетов |
| POST |
/api/v0/widgets |
Создать виджет |
| GET |
/api/v0/widgets/:publicID |
Виджет по public id |
| PUT |
/api/v0/widgets/:publicID |
Обновить виджет |
| PATCH |
/api/v0/widgets/:publicID |
Частично обновить виджет |
| DELETE |
/api/v0/widgets/:publicID |
Удалить виджет |
Resources v1 (/api/v1/resource, /api/v1/targets, /api/v1/service-accounts)
| Метод |
Путь |
Назначение |
| GET |
/api/v1/resource |
Список ресурсов (v1) |
| POST |
/api/v1/resource |
Создать ресурс |
| GET |
/api/v1/resource/:publicID |
Ресурс по public id |
| PUT |
/api/v1/resource/:publicID |
Обновить ресурс |
| PATCH |
/api/v1/resource/:publicID |
Частично обновить ресурс |
| DELETE |
/api/v1/resource/:publicID |
Удалить ресурс |
| GET |
/api/v1/targets/:target_id/resource |
Ресурс по target id (только внутренний) |
| GET |
/api/v1/resources-grouped-by-sa |
Ресурсы, сгруппированные по сервисному аккаунту (если включено) |
| GET |
/api/v1/service-accounts |
Список сервисных аккаунтов |
Widgets v2 (/api/v2/resource)
| Метод |
Путь |
Назначение |
| GET |
/api/v2/resource |
Список виджетов (v2) |
| POST |
/api/v2/resource |
Создать виджет |
| GET |
/api/v2/resource/:publicID |
Виджет по public id |
| PUT |
/api/v2/resource/:publicID |
Обновить виджет |
| PATCH |
/api/v2/resource/:publicID |
Частично обновить виджет |
| DELETE |
/api/v2/resource/:publicID |
Удалить виджет |
Permissions v1 (/api/v1)
| Метод |
Путь |
Назначение |
| GET |
/api/v1/resource_permission |
Список прав на ресурсы |
| POST |
/api/v1/resource_permission |
Создать права (пакет items[]) |
| GET |
/api/v1/resource_permission/:id |
Право по id |
| DELETE |
/api/v1/resource_permission/:id |
Удалить право |
| PATCH |
/api/v1/permissions-bulk |
Массовое изменение прав (tenant_id, permissions) |
| GET |
/api/v1/company_resource_permission |
Список прав компании на ресурсы |
| POST |
/api/v1/company_resource_permission |
Создать права компании (пакет items[]) |
| GET |
/api/v1/company_resource_permission/:id |
Право компании по id |
| DELETE |
/api/v1/company_resource_permission/:id |
Удалить право компании |
Внешний контур (/external/api/*, только при AUTH_ENABLED=true)
Публикуется подмножество внутренних маршрутов; часть — только на чтение. Пути идентичны внутренним, но с префиксом /external/api.
| Группа |
Маршруты |
Отличия от внутреннего контура |
/external/api/v0/users |
GET /, GET /:id, PATCH / |
Только чтение + массовый PATCH (bulk) |
/external/api/admin/v0/users |
POST /activation, полный CRUD /users |
Полный доступ (админ-группа) |
/external/api/admin/v0/positions |
/positions (CRUD) |
Как внутренний |
/external/api/admin/v0/departments |
/departments (CRUD) |
Как внутренний |
/external/api/admin/v0/groups |
/groups (CRUD + search) |
Как внутренний |
/external/api/admin/v0/permissions |
/permissions (django) |
Как внутренний |
/external/api/v0/resource-types |
/resource-types (CRUD) |
Как внутренний |
/external/api/v0/resources |
/resources (CRUD, v0) |
Как внутренний |
/external/api/v0/projects |
GET /, GET /:publicID |
Только чтение |
/external/api/v0/widgets |
/widgets (CRUD) |
Как внутренний |
/external/api/v1/resource |
GET /, GET /:publicID |
Только чтение |
/external/api/v2/resource |
/resource (виджеты v2, CRUD) |
Как внутренний |
/external/api/v1/resource_permission |
CRUD-подмножество |
Как внутренний |
/external/api/v1/permissions-bulk |
PATCH / |
Как внутренний |
/external/api/v1/company_resource_permission |
CRUD-подмножество |
Как внутренний |
Часть маршрутов регистрируется условно — только если соответствующий хендлер/use case подключён при инициализации сервера (проверки Has* в хендлерах). При отсутствии сервиса группа не регистрируется.