Перейти к содержанию

Администрирование

Эта страница — про Admin UI и админский REST API: роли, кто что может делать, и три конкретных сквозных потока, которые чаще всего вызывают вопросы — approve/reject/revoke, блокировка устройства при отзыве и сервисные аккаунты. Про сами переменные окружения и установку сервера — Конфигурация и Установка.

Роли

Ровно четыре роли, назначаются через PUT /api/v1/users/{email}/roles (cert-admin only) или, для локальных пользователей, при создании через POST /api/v1/users/local:

Роль Кому назначается Доступ
cert-admin Людям Полный доступ: все read-эндпоинты + весь write (approve/reject/revoke, block/unblock, пользователи и роли, сети, сервисные аккаунты, вебхуки, лицензия, настройки).
cert-approver Людям Чтение заявок/устройств/аудита/сетей/статистики + approve. Не может reject, revoke, управлять пользователями/сетями/сервисными аккаунтами.
cert-viewer Людям Только чтение — те же read-эндпоинты, что у cert-approver, без approve.
cert-auto-approver Только сервисным аккаунтам — людям эта роль не назначается Наименьшие привилегии: POST /requests/approve + чтение /requests и /requests/check-conflicts. Не видит /audit, /devices, сети, статистику — только то, что нужно, чтобы обнаружить заявку и проверить конфликты перед одобрением.

Первый залогинившийся пользователь автоматически получает cert-admin (атомарная вставка в пустую user_roles, работает и для Keycloak, и для локальной аутентификации).

Keycloak-only деплой без local-admin bootstrap

Если API открыт наружу раньше, чем оператор сам первый раз залогинился, «первый залогинившийся» — это буквально первый обладатель валидного токена сконфигурированного Keycloak-клиента, а не обязательно оператор. Закрывайте это до открытия API наружу: либо залогиньтесь первым сами, либо настройте local-admin bootstrap (ALATYR_LOCAL_AUTH_ENABLED + ALATYR_LOCAL_ADMIN_EMAIL/ALATYR_LOCAL_ADMIN_PASSWORD, см. Конфигурация), либо предзаполните нужную строку user_roles вручную.

Обзор разделов Admin UI

Раздел Доступ на чтение Доступ на запись
Dashboard / статистика cert-admin/cert-approver/cert-viewer
Заявки (Requests) + cert-auto-approver (только список и check-conflicts) approve — cert-admin/cert-approver/cert-auto-approver; reject — cert-admin
Устройства (Devices), логи устройств cert-admin/cert-approver/cert-viewer request/cancel/delete логов, revoke enrollment-token, revoke/unblock устройства — cert-admin
Сертификаты cert-admin/cert-approver/cert-viewer (bundle) revoke сертификата — cert-admin
SSH Keys cert-admin/cert-approver/cert-viewer approve/reject/revoke — cert-admin; см. SSH Key Registry
Аудит cert-admin/cert-approver/cert-viewer — (аудит только читается)
Пользователи и роли cert-admin cert-admin
Сети (Wi-Fi/802.1X) cert-admin/cert-approver/cert-viewer cert-admin
Сервисные аккаунты cert-admin (недоступно самим сервисным аккаунтам) cert-admin
Вебхуки cert-admin cert-admin
Настройки — Issuers / Issue Policy / Security Defaults / Licensing (подробнее) / Agent Update / Source-auth любая admin-роль (read) cert-admin
Настройки — Corp Verify (allowlist), SSH-ключи (keyholder tokens) cert-admin (read тоже, не «любая admin-роль») cert-admin

Настройки — не единый блок прав

Вкладка «Настройки» неоднородна по доступу на чтение. Issuers / Issue Policy / Security Defaults / Licensing / Agent Update / Source-auth (GET /api/v1/settings/system, GET /api/v1/settings/sa-auto-approve, GET /api/v1/settings/enroll-source-auth) читает любая admin-роль — пишет только cert-admin. А вот Corp Verify allowlist (GET /api/v1/admin/corp-allowlist) и список/CRUD keyholder-токенов на вкладке SSH-ключи (GET/POST/DELETE /api/v1/admin/keyholder-tokens) зарегистрированы в том же cert-admin-only route group, что и запись — там нет отдельного read-доступа для cert-approver/cert-viewer, в отличие от остальных вкладок настроек.

Аутентификация источника заявки (enroll source-auth)

Эндпоинты /enroll* (/enroll, /enroll/user, /enroll/ssh) принципиально не требуют авторизации — у агента ещё нет токена при первом обращении к серверу. Без дополнительной проверки это означает, что запрос от произвольного HTTP-клиента с корректно оформленным телом (даже без аппаратной аттестации или с поддельной) всё равно получит статус pending, неотличимо от заявки настоящего агента: сама по себе аттестация рекомендательна и не блокирует создание заявки.

enroll source-auth закрывает этот разрыв: агент подписывает тело заявки тем же аппаратным ключом (TPM AK-ключ на Windows/Linux, ключ Secure Enclave на macOS), которым построен CSR, а сервер проверяет эту подпись против открытого ключа из самого CSR ещё до создания заявки — то есть до того, как она вообще получит статус pending.

Режим — fleet-wide настройка с четырьмя уровнями, каждый следующий строже предыдущего:

Режим Поведение
off (по умолчанию) Поведение не меняется; статус проверки только записывается для наблюдаемости.
version_floor Отклоняет (403) агентов ниже заданной минимальной версии — миграционный инструмент, чтобы сначала перевести флот на сборки, умеющие подписывать заявку, а не самостоятельная защита.
attestation_hardgate Требует и проверяет аппаратную подпись заявки; при отсутствующей или невалидной подписи заявка отклоняется (403) ещё до создания строки.
strict То же, что attestation_hardgate, плюс синхронная проверка полной цепочки аппаратной аттестации для Windows/Linux (TPM); для macOS цепочка не проверяется — Secure Enclave не даёт внешне проверяемой EK-цепочки, поэтому там принимается сама подпись. Программный (не аппаратный) ключ отклоняется на любой платформе.

Отклонение на любом из включённых режимов возвращает одну и ту же ошибку 403 enroll_source_auth_failed — по коду ошибки нельзя определить, что именно не совпало: версия, подпись или цепочка аттестации.

Когда включать. Функция рассчитана на поэтапный запуск: сначала off (чтобы через ваш обычный канал распространения пакетов сначала попали сборки с поддержкой подписи), затем version_floor (вытеснить старые агенты), затем attestation_hardgate, и только после стабилизации — strict. Переход сразу к strict не рекомендуется.

Управление. Режим настраивается на вкладке «Source-auth» в Admin UI или через GET/PUT /api/v1/settings/enroll-source-auth (чтение — любая admin-роль, запись — только cert-admin). Каждое изменение режима попадает в Аудит с указанием, кто и когда его изменил и какими были значения до и после.

Approve / reject / revoke заявок

Заявки на выпуск создаются только через неавторизованные /enroll*-эндпоинты (по enrollment_token устройства) и всегда попадают в pending — ни один purpose (wifi/user_mtls/ad_logon/ssh) не выдаётся автоматически при регистрации, обязательно ручное или сервис-аккаунтное решение.

  • POST /api/v1/requests/approve (bulk) — cert-admin, cert-approver или сервисный аккаунт с ролью cert-auto-approver. Прежде чем одобрить, сервис-аккаунтные вызовы проходят независимую последовательность проверок: аппаратная аттестация, соответствие purpose, при включённой corp-ownership-проверке — allowlist/webhook (см. ниже), и блокировка устройства (см. следующий раздел). При интерактивном одобрении человеком эти проверки не выполняются — approve всегда разрешён (кроме терминальных статусов заявки).
  • POST /api/v1/requests/reject (bulk) — только cert-admin.
  • POST /api/v1/certificates/{serial}/revoke — только cert-admin. Для SCEP-выпущенных сертификатов недоступен (у SCEP нет операции отзыва — кнопка отключена в UI, API вернёт 400); отзывайте на стороне CA напрямую.

Corp-ownership verification для сервис-аккаунтного auto-approve (system_settings.sa_auto_approve_verifier, GET/PUT /api/v1/settings/sa-auto-approve) — дополнительный, независимый от аппаратной аттестации сигнал: off (по умолчанию), allowlist (серийный номер должен быть в corp_device_allowlist, CRUD — cert-admin, /api/v1/admin/corp-allowlist), webhook (SSRF-safe запрос на админ-настроенный URL), либо комбинаторы allowlist_or_webhook / allowlist_and_webhook. Отсутствие настройки или ошибка проверки никогда не трактуется как разрешение — обе проверки fail-closed.

Блокировка устройства при отзыве (device-block-on-revoke)

Полный отзыв устройства — POST /api/v1/devices/{serial}/revoke (cert-admin) — отзывает все активные сертификаты устройства и, только если абсолютно все они отозвались успешно, дополнительно ставит на устройство постоянную блокировку: blocked_at/blocked_by/blocked_reason, аудит-запись device.block. Частичный сбой отзыва (HTTP 207) блокировку не ставит — та же проверка, что уже защищает освобождение license-слота (см. Лицензирование).

  • POST /api/v1/devices/{serial}/unblock (cert-admin, идемпотентен) — единственный способ снять блокировку: явное, обратимое человеческое действие. Повторный вызов на уже разблокированном устройстве — success, без ошибки. Unblock не трогает pending-заявки.
  • Пока устройство заблокировано, все три enroll-эндпоинта (/enroll, /enroll/user, /enroll/ssh) по-прежнему создают обычную pending заявку — никогда не 403 — но помечают её enrolled_while_blocked = true. Этот флаг постоянный: последующий unblock устройства его не очищает, это точечная историческая запись про конкретную заявку.
  • При сервис-аккаунтном одобрении заявка безусловно отклоняется, если enrolled_while_blocked = true или устройство заблокировано в момент проверки. Оба сигнала проверяются независимо: иначе заявка, оставшаяся pending к моменту блокировки устройства (а потому не помеченная флагом задним числом), прошла бы автоодобрение. Человек может одобрить такую заявку интерактивно в любой момент — это не снимает блокировку устройства, для этого нужен отдельный явный unblock.

Известное ограничение

Блокировка привязана к строке devices, которая определяется по заявленному агентом serial_number — устройство, физически контролирующее собственный агент (ровно модель угрозы этого механизма), может обойти блок, заявив другой серийный номер (новая незаблокированная строка) или, для placeholder-серийников, просто не предъявив continuity_key при повторном enroll. Это не новая брешь — то же самое уже верно для отзыва сертификата на уровне устройства. Также блокировка не останавливает уже выданные SSH-ключи из SSH Key Registry — см. предупреждение на странице SSH Key Registry.

Для флота с TPM этот обход закрывается включением TPM_REJECT_UNATTESTED / TPM_REQUIRE_AK_CERTIFY — заявленный серийный номер тогда должен совпадать с аттестованным железом.

Сервисные аккаунты

Машинные идентичности для API-based approve (CI/автоматизация) вместо интерактивного логина. Управление — только cert-admin, недоступно самим сервисным аккаунтам (guard против privilege escalation — SA не может создать или изменить другой SA):

Метод и путь Назначение
GET /api/v1/service-accounts Список
POST /api/v1/service-accounts Создать; токен wca_* показывается один раз в ответе
PUT /api/v1/service-accounts/{id}/enabled Включить/выключить
DELETE /api/v1/service-accounts/{id} Удалить
  • В БД хранится только SHA-256-хеш токена; сырое значение — только при создании.
  • Токен с префиксом wca_ распознаётся до проверки JWT; fail-closed (401 на неизвестный/выключенный токен или ошибку БД).
  • Срок действияexpires_in_days при создании (0–3650; 0/пусто — бессрочный). Истёкший токен отклоняется (401), fail-closed.
  • Аудитaudit_log.actor_kind различает user (веб-сессия) и service_account (API-токен); UI показывает тег «API» на действиях сервисного аккаунта.
  • Единственное мутирующее действие, которое достижимо SA-токеном — POST /requests/approve; reject/revoke/управление пользователями и сетями остаются cert-admin-only независимо от токена.

Пользователи и роли

PUT /api/v1/users/{email}/roles и PUT /api/v1/users/{email}/enabled (cert-admin) управляют ролями и активностью учётной записи. Локальные (не-SSO) пользователи создаются и управляются отдельными эндпоинтами (POST /api/v1/users/local, PUT /api/v1/users/{email}/password) — детали локальной аутентификации и bootstrap первого администратора см. в разделе про локальную аутентификацию на странице Конфигурация.

Сети (Wi-Fi + проводной 802.1X)

cert-admin создаёт/отключает/восстанавливает/удаляет записи в едином списке сетей (kind = wifi или wired, не более одной активной wired-сети). Там же, для каждой сети отдельно, три переключателя «распространять профиль через агента» — по одному на macOS/Windows/Linux — для флотов, где эти профили раскатываются через MDM/GPO/config management, а не самим агентом. Механика этих переключателей и их fleet-wide аналог для macOS — на странице Агенты.