Лицензия
Как устроена лицензия установки на своих серверах: установка ключа, просмотр состояния, поведение при истечении, какие ограничения применяются на самом деле.
На этой странице
Лицензия — это подписанный вендором файл, который разрешает установке запись
данных и включает набор возможностей. Она существует только в установке на своих
серверах: в облаке те же решения принимает подписка, и маршруты лицензии там не
смонтированы вовсе — запрос к ним возвращает 404. Эта страница нужна, когда вы
устанавливаете ключ впервые, продлеваете срок или разбираетесь, почему запись
перестала работать.
Как устроена лицензия
Ключ подписан вендором по схеме Ed25519. Проверка полностью офлайновая: сервер
никуда не обращается, а сверяет подпись публичным ключом из переменной окружения
LICENSE_PUBKEY. Сам ключ лицензии в переменных окружения не задаётся — он
загружается через API или кабинет и хранится в базе данных установки.
| Что нужно | Где задаётся | Обязательно |
|---|---|---|
LICENSE_PUBKEY — публичный ключ вендора для проверки подписи |
.env установки |
да |
| Ключ лицензии | загружается через /api/v1/license или экран кабинета |
да |
Ключ — одна строка из двух частей в base64, разделённых точкой. Переносы строк при копировании — самая частая причина отказа: вставляйте значение целиком, без пробелов и переводов строки.
В подписанном содержимом ровно пять полей: организация, код тарифа, договорный объём событий в месяц, срок действия и перечень возможностей. Срок действия есть всегда: ключ без срока не считается действующим, бессрочных лицензий не бывает.
Как установить ключ
Установка требует роли owner — той самой учётной записи, которая создаётся при
первом старте из BOOTSTRAP_EMAIL и BOOTSTRAP_PASSWORD. Режим поддержки
(impersonation) к этой операции не допускается.
В кабинете экран лежит в разделе Настройки → Лицензия: там же видно текущее состояние, срок и перечень возможностей. Путь через API ниже не зависит от того, как в вашей установке отдаётся статика кабинета.
# 1. Токен доступа (живёт 15 минут). Пароль читается из приглашения и не
# попадает ни в историю команд, ни в список процессов.
read -rp 'email: ' PP_EMAIL
read -rsp 'password: ' PP_PASSWORD && echo
export PP_EMAIL PP_PASSWORD
TOKEN=$(python3 -c 'import json,os;print(json.dumps({"email":os.environ["PP_EMAIL"],"password":os.environ["PP_PASSWORD"]}))' \
| curl -fsS -X POST "https://${PP_DOMAIN}/api/v1/auth/login" \
-H 'Content-Type: application/json' --data @- \
| python3 -c 'import json,sys;print(json.load(sys.stdin)["access_token"])')
unset PP_PASSWORD
# 2. Установка ключа из файла, выданного вендором.
python3 -c 'import json,sys;print(json.dumps({"key":open(sys.argv[1]).read().strip()}))' license.key \
| curl -fsS -X PUT "https://${PP_DOMAIN}/api/v1/license" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' --data @-
# 3. Проверка состояния.
curl -fsS "https://${PP_DOMAIN}/api/v1/license" -H "Authorization: Bearer $TOKEN"
Если у учётной записи включён второй фактор, вход принимает дополнительное поле
mfa_code — текущий шестизначный код или один неиспользованный код
восстановления.
Ответ на установку короткий: {"valid":true,"read_only":false,"reason":"active"}.
Ключ, который не прошёл проверку, не заменяет действующую лицензию: он не
сохраняется вовсе, а запрос отвечает 422 с кодом license_invalid и причиной в
сообщении. Пустое значение key — 422 с кодом validation_failed.
Как посмотреть состояние
GET /api/v1/license доступен любому участнику организации с действующим
токеном — читать состояние может не только владелец. Значения в примере ниже
условные, в вашем ответе они придут из вашего ключа:
{
"valid": true,
"read_only": false,
"reason": "active",
"org": "ACME",
"plan": "growth",
"expires_at": "2027-01-31T00:00:00Z",
"max_events_month": 50000000,
"features": ["basic_reports", "dashboards_private", "sql_console"]
}
| Состояние | Что видно в ответе | Что это значит |
|---|---|---|
| Действует | valid: true, read_only: false, reason: active |
запись и чтение работают |
| Истекает | то же, но expires_at близко |
кабинет показывает предупреждение за 14 дней до срока |
| Только чтение | valid: true, read_only: true |
срок прошёл, идёт 7-дневный льготный период |
| Недействительна | valid: false |
подписи нет, она не сходится, ключ не загружен или льготный период закончился |
Если состояние прочитать не удалось (например, недоступна база данных), GET
отвечает 503 с кодом license_invalid — это не приговор лицензии, а
недоступность проверки. Поведение при этом fail-closed: запись тоже запрещается.
Что происходит при истечении и недействительности
Проверка стоит на всех изменяющих запросах основного API — POST, PUT,
PATCH, DELETE — и на приёме событий. Отказ выглядит так:
| Ситуация | Код | error.code |
Сообщение |
|---|---|---|---|
| Ключ не загружен, подпись не сходится, льготный период закончился | 403 |
license_invalid |
license invalid or missing: <причина> |
| Срок прошёл, идёт льготный период | 403 |
license_invalid |
license expired; running read-only until renewed |
| Состояние лицензии не удалось прочитать | 403 |
license_invalid |
license status is temporarily unavailable |
Что продолжает работать без действующей лицензии:
- чтение — отчёты, панели, списки, выгрузка результата отчёта;
- вход, обновление сессии и выход: маршруты аутентификации вне этой проверки;
- сам путь
/api/v1/license— иначе новый ключ было бы нечем загрузить; - запросы отчётов, которые используют
POSTтолько для передачи описания запроса (воронки, удержание, сегментация, пути, атрибуция, предпросмотр сводок, обновление панели, выгрузка результата); - удаление данных субъекта:
POSTна путь стирания выведен из-под проверки намеренно — исполнение права на забвение не должно зависеть от коммерческого состояния установки.
Как быстро подхватывается новый ключ
Основной API и воркер перечитывают состояние из базы данных не реже раза в секунду, поэтому замена ключа действует практически сразу и перезапуск не нужен.
Приём событий устроен иначе: он никогда не видит сам ключ. Воркер проверяет подпись и публикует нормализованную проекцию прав, а приём читает только её. Проекция обновляется каждые 30 секунд и считается свежей 2 минуты.
Какие ограничения лицензия действительно применяет
Самое важное отличие «того, что написано в ключе» от «того, что работает»:
| Поле ключа | Применяется во время работы | Комментарий |
|---|---|---|
expires_at |
да | срок, льготный период, режим только чтения |
features |
да | проверяется на каждом обращении к API и перед каждым фоновым запуском |
plan |
нет сам по себе | код тарифа из того же каталога, что и в облаке; фактический набор возможностей задаёт features |
org |
нет | отображается в кабинете |
max_events_month |
нет | договорной объём, метаданные договора |
Перечень features использует те же коды возможностей, что и облачный каталог
тарифов: отдельного «on-prem словаря» не существует. Вне зависимости от ключа
всегда доступны базовые отчёты, приватные панели, автоматический сбор событий и
удаление данных субъекта — это неотключаемая основа, а не пункт договора.
Сроки хранения данных в установке на своих серверах не зависят от лицензии и заданы фиксированно: события — 25 месяцев, записи сессий — 90 дней. Отдельного поля хранения в ключе нет, и настройки хранения в кабинете тоже нет.
Пробных периодов в установке на своих серверах не бывает: отказ всегда приходит по пути лицензии, а не как «оформите подписку».
Чем лицензия отличается от облачной подписки
| Установка на своих серверах | Облако | |
|---|---|---|
| Источник прав | подписанный ключ | тариф подписки из каталога |
| Раздел биллинга в API | не смонтирован, 404 |
есть |
| Пробный период | нет | есть у одного тарифа |
| Отказ при отсутствии прав | 403 license_invalid |
402 subscription_required, 403 feature_locked |
| Лимит событий | метаданные договора, не применяется | применяется, при превышении приём отвечает 429 |
| Хранение | фиксировано установкой | определяется тарифом |
| Продление | новый ключ от вендора | оплата в кабинете |
Что проверить и частые ошибки
GET /api/v1/licenseвозвращает"valid": trueи"read_only": false. Это единственный достоверный признак, что запись разрешена.- Запись действительно работает: создайте тестовый объект или отправьте тестовое
событие. Проверка работоспособности лицензию не смотрит и отвечает
200даже без неё. LICENSE_PUBKEYзаполнен. С пустым или испорченным значением любой ключ выглядит недействительным — причина в ответе будет указывать на публичный ключ, а не на ключ лицензии.- Ключ вставлен одной строкой. Перенос строки внутри значения даёт отказ по разбору.
- Время на хосте синхронизировано. Срок сравнивается с системным временем: ушедшие вперёд часы «истекают» рабочую лицензию, ушедшие назад — маскируют истечение.
- Контейнер
workerработает. Отказ приёма событий по лицензии при исправном ключе — это почти всегда остановленный воркер. - Установили новый ключ, а состояние прежнее — проверьте, что запрос вернул
200, а не422: отклонённый ключ не заменяет действующую лицензию. - За 14 дней до срока кабинет показывает предупреждение. Считайте его сигналом запрашивать продление, а не поводом дождаться льготного периода.