Администрирование¶
Эта страница — про 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 — на странице Агенты.