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

Лицензирование

Число одновременно обслуживаемых устройств ограничено действующей лицензией. Эта страница описывает, как определяется лимит, как посмотреть текущий статус, как применить приобретённую лицензию, что происходит при приближении к лимиту или его превышении и как освобождать слоты при выводе устройств из эксплуатации. Список эндпоинтов — в REST API; про роли — в Администрирование.

Как определяется лимит

Действующая лицензия — это подписанный вендором файл, применённый к конкретному развёртыванию. Если ни одна лицензия не была загружена, сервер использует лицензию по умолчанию с лимитом 50 устройств — дополнительных действий для работы в этом режиме не требуется. Загруженная платная лицензия задаёт собственный лимит (max_devices) и, как правило, срок действия.

Проверка текущего статуса

GET /api/v1/license/status

Доступен любой admin-роли (cert-admin/cert-approver/cert-viewer). Пример ответа:

{
  "mode": "free",
  "tier": "free",
  "issued_to": "bundled-free",
  "active_count": 12,
  "max_devices": 50,
  "high_water": 14,
  "expires_at": "2125-01-01T00:00:00Z",
  "tamper": false,
  "deployment_instance_key": "base64-ed25519-pubkey..."
}
Поле Значение
tier Тариф действующей лицензии: free или paid
mode Состояние: licensed (действует платная), free (лицензия не загружалась), expired (платная загружена, но срок истёк — мягкий откат к базовому лимиту)
active_count Сколько устройств сейчас учтено лицензией
max_devices Текущий лимит
high_water Наибольшее значение, которое даёт пересчёт журнала (используется при восстановлении журнала, см. ниже; после восстановления журнала может уменьшиться)
expires_at Срок действия применённой лицензии
tamper Флаг деградированного режима из-за нарушения целостности журнала учёта (см. ниже)
deployment_instance_key Публичный Ed25519-ключ этого развёртывания, сгенерированный при первом запуске; не секрет, используется только для привязки лицензии к конкретному развёртыванию

Тот же статус отображается на странице Настройки → Лицензия в Admin UI в виде баннера и карточки статуса — раздел «Настройки» есть в навигации только у роли cert-admin; применение лицензии и decommission на ней тоже доступны только cert-admin. Предупреждающий баннер при этом показывается всем ролям на любой странице (см. Администрирование).

Применение приобретённой лицензии

  1. Получите deployment_instance_key этого развёртывания — из ответа GET /api/v1/license/status или со страницы «Лицензия» в Admin UI (поле с копированием в буфер).
  2. Передайте этот ключ вместе с нужным количеством устройств при оформлении покупки. Лицензия выпускается вендором привязанной к этому ключу.
  3. Полученный файл лицензии (.lic) примените одним из способов:
  4. в Admin UI: страница «Лицензия» → вставить или загрузить файл → Активировать;
  5. через API:
    POST /api/v1/license/activate
    {"license_b64": "<base64-содержимое .lic-файла>"}
    
    (cert-admin).
  6. Сервер проверяет подпись вендора и соответствие поля instance_public_key внутри файла лицензии ключу этого развёртывания — тому самому, что отдаётся эндпоинтом статуса под именем deployment_instance_key (это один и тот же Ed25519-ключ, только под разными именами: deployment_instance_key — как его возвращает API этого развёртывания, instance_public_key — как он записан внутри выпущенного файла лицензии). При несовпадении или повреждённой подписи запрос отклоняется (400 {"code":"license_invalid"}), а ранее действовавшая лицензия (платная или базовая) остаётся в силе без изменений.

После успешного применения GET /api/v1/license/status отражает новый tier и max_devices.

Аттестация лицензии агентом

POST /api/v1/license/attest — публичный, не требующий авторизации эндпоинт (ограничен тем же rate-limit, что и /enroll). Им пользуется не администратор, а сам агент: перед тем как сгенерировать ключевой материал и CSR, агент запрашивает у сервера действующую лицензию вместе с подписью, подтверждающей — над присланным агентом нонсом, — что ответ пришёл именно от этого развёртывания, и проверяет её встроенным вендорским ключом. Если проверка не проходит, агент прерывает enrollment ещё до обращения к TPM/Secure Enclave. Для администрирования лицензии этот эндпоинт не нужен — он описан здесь для полноты картины REST API.

Поведение лицензии по ситуациям

Ситуация Действующая лицензия
Лицензия ни разу не загружалась Базовая, лимит 50 устройств
Загружена валидная платная лицензия, срок не истёк Эта лицензия, лимит max_devices
Платная лицензия загружена, но expires_at в прошлом Мягкий откат к базовой (лимит 50) — не блокировка. На UI — баннер «лицензия истекла, требуется продление». Устройства, уже превышающие 50, сохраняют выданные сертификаты; новая выдача ограничена лимитом 50
Загруженный файл не проходит проверку подписи/привязки Отклоняется целиком (400 license_invalid), действующая лицензия не меняется

Уже выданные сертификаты и их продление изменением лицензии никогда не затрагиваются — лимит влияет только на выдачу сертификата новому устройству.

Что засчитывается в лимит

Устройство засчитывается в момент первой выдачи ему сертификата этой системой, независимо от используемого issuer-бэкенда. Устройство идентифицируется по аппаратно закреплённому ключу, в порядке приоритета:

  1. серийный номер EK-сертификата (TPM на Windows и Linux, Secure Enclave на macOS) — единственный вариант, который нельзя разделить между разными машинами;
  2. серийный номер устройства — если аппаратной аттестации нет;
  3. хеш публичного ключа из CSR — резервный вариант, если серийный номер пуст или является известным заглушечным значением.

Продление сертификата уже учтённого устройства нового слота не расходует.

Отзыв, удаление записи и decommission — в чём разница

Три разных действия часто путают, потому что визуально они происходят на соседних страницах Admin UI:

  • Отзыв сертификата (страница «Сертификаты», POST /api/v1/certificates/{serial}/revoke, а также POST /api/v1/users/{identity}/revoke-certs) отзывает конкретный сертификат через CA. Сам по себе слот лицензии не освобождает — устройство остаётся учтённым в лимите, пока за ним не выполнен decommission.
  • Удаление записи устройства или сертификата из данных системы слот тоже не освобождает: журнал учёта хранит идентичность устройства независимо от того, существует ли ещё соответствующая строка в таблицах устройств/заявок.
  • Decommission — единственное действие, которое освобождает слот (снижает active_count). Оно бывает в двух формах:
    • явнойcert-admin вызывает его напрямую для конкретной идентичности устройства (см. следующий раздел);
    • автоматической, как часть полного отзыва устройства («убить устройство», POST /api/v1/devices/{serial}/revoke, cert-admin): эндпоинт отзывает все активные сертификаты устройства и, только если каждый из них отозвался успешно, сам выполняет decommission этого устройства и дополнительно ставит на него блокировку от переустановки (см. Администрирование). Частичный сбой отзыва хотя бы одного сертификата (HTTP 207) слот не освобождает и блокировку не ставит — повторный вызов того же эндпоинта безопасен и либо дозавершит отзыв оставшихся сертификатов, либо, если все они уже отозваны, доведёт до конца сам decommission.

Освобождение слота при выводе устройства из эксплуатации

Когда оборудование выведено из эксплуатации, cert-admin может освободить его слот явным decommission-действием, не дожидаясь отзыва сертификатов (например, если устройство физически утеряно и сертификат уже истёк сам):

POST /api/v1/license/decommission
{"identity_key": "ek:... | sn:... | pk:..."}

Действие снижает счётчик активных устройств на единицу, освобождая слот. Обратить его можно только повторным enroll этого устройства. Отдельной записи в журнале аудита Admin UI это действие не создаёт. Прямое удаление записей устройства или сертификата на это не влияет.

Ключ идентичности устройства не выводится ни в Admin UI, ни через API — и в штатном сценарии он не нужен: вывод устройства из эксплуатации делается через POST /api/v1/devices/{serial}/revoke, который выполняет decommission сам (см. «Отзыв, удаление записи и decommission» выше). Явный decommission по ключу — на случай, когда ключ известен заранее.

Коды ошибок при выдаче

Проверка лимита выполняется в момент одобрения заявки (approve), а не при её создании — заявка, ожидающая одобрения, слот не занимает.

  • 402, code=license_limit — новое устройство превысило бы max_devices. В UI это ведёт к предложению приобрести дополнительный лимит.
  • 402, code=license_tamper — не пройдена проверка целостности журнала учёта устройств (см. ниже).
  • Эти коды возвращаются как HTTP-статус, когда одобряется одна заявка. При массовом одобрении ответ остаётся 200, а отказ виден в соответствующей строке массива результатов (status: "error", error: "license_limit" / "license_tamper").
  • Продление и переиздание сертификата для уже учтённого устройства ни одним из этих кодов не блокируется.

Нарушение целостности журнала учёта и восстановление

Учёт устройств ведётся во внутреннем журнале с проверкой целостности. Сервер проверяет его при старте и перед каждой новой засчитываемой выдачей сертификата. Если журнал не проходит проверку — например, его записи были изменены в обход штатных операций, — сервер переходит в режим tamper:

  • новая выдача/одобрение сертификатов блокируется: 402 {"code":"license_tamper"};
  • в интерфейсе появляется предупреждающий баннер; отдельной записи в журнале аудита это не создаёт — факт фиксируется в журналах сервера, в том числе строкой при старте;
  • уже выданные сертификаты и их продление не затрагиваются — режим tamper блокирует только новую засчитываемую выдачу.

Это деградированное, но не постоянное состояние. cert-admin может восстановить журнал:

POST /api/v1/license/reanchor

Операция восстанавливает журнал по сохранившимся данным и фиксирует новое состояние. Восстановление не может занизить учтённое количество устройств: итоговое значение — максимум из (а) того, что даёт пересчёт уцелевших записей журнала, (б) числа устройств с реально выпущенными и неотозванными сертификатами и (в) счётчика из последней криптографически подтверждённой контрольной точки журнала. Ранее достигнутый пик (high_water) в этот расчёт не входит — легитимно списанные через decommission устройства после восстановления не «воскресают». Единственный штатный способ понизить active_count — decommission (явный вызов или как часть полного отзыва устройства, см. «Отзыв, удаление записи и decommission» выше) на исправном журнале.

Практическое следствие

Если после нарушения целостности часть записей журнала утеряна, восстановление добирает недостающие слоты записями-заглушками. Такие слоты занимают лимит наравне с реальными устройствами, пока администратор не выполнит для них decommission явно.

Что мониторить

  • active_count относительно max_devices — приближение к лимиту стоит планировать заранее, чтобы выдача новых сертификатов не остановилась в неподходящий момент.
  • expires_at — истечение платной лицензии не блокирует систему, но откатывает лимит к 50 устройствам.
  • tamper — появление true требует внимания администратора и, как правило, восстановления журнала через reanchor.

Все три поля доступны через GET /api/v1/license/status и подходят для периодического опроса без похода в UI.