JWT и сервисные учетные записи
VideoGrace Server может выпускать стандартные bearer JWT для браузерных клиентов, REST API, media/blob каналов и сервисных worker'ов. JWT-flow нужен для PWA, внешних сервисов, транскрибера, recorder/consolidator pipeline и будущих интеграций без передачи пользовательских паролей.
Включение JWT
Задайте общий серверный secret:
[Auth]
JwtSecret = <длинный_случайный_секрет>
JwtTtlSec = 604800
RefreshTtlSec = 2592000
Эквивалентные переменные окружения:
VG_JWT_SECRET=<длинный_случайный_секрет>
VG_JWT_TTL_SEC=604800
VG_REFRESH_TTL_SEC=2592000
Параметры:
| Параметр | Назначение |
|---|---|
JwtSecret / VG_JWT_SECRET |
Секрет HMAC-SHA256 для подписи access JWT. |
JwtTtlSec / VG_JWT_TTL_SEC |
Время жизни access token, по умолчанию 7 дней. |
RefreshTtlSec / VG_REFRESH_TTL_SEC |
Время жизни refresh token, по умолчанию 30 дней. |
Если secret не задан, сервер может работать с legacy opaque token. Для production и сервисной авторизации задайте JWT-secret обязательно.
Что хранится в БД
Начиная с версии БД 3.0.260531 сервер создает таблицы:
| Таблица | Назначение |
|---|---|
refresh_tokens |
HMAC-хеши refresh token, client_id, время выпуска и истечения. |
jwt_revoked |
Отозванные jti access JWT до окончания их TTL. |
service_accounts |
Привязка имени сервиса к обычному пользователю VideoGrace. |
Access JWT не хранится в БД. Refresh token хранится только в виде хеша.
Обновление access token
Клиент получает refresh_token при первичном входе и затем может запросить новый access token:
POST /api/v1.0?auth_refresh
Content-Type: application/json
{
"refresh_token": "..."
}
Ответ:
{
"result": 200,
"access_token": "...",
"token_type": "Bearer"
}
Refresh token нельзя использовать как bearer token для REST, media, blob или CAN.
Отзыв токенов
Точечный отзыв access JWT выполняется через jti:
insert into jwt_revoked (jti, expires_at, created_at, reason)
values ('<jwt_jti>', <jwt_exp>, strftime('%s','now'), 'admin revoke');
Чтобы сбросить все access JWT, смените JwtSecret и перезапустите сервер. Это разлогинит активные JWT-сессии, поэтому выполняйте операцию в окно обслуживания.
Чтобы отозвать refresh token конкретного пользователя:
delete from refresh_tokens
where client_id = <client_id>;
Service account для Transcriber
Создайте отдельного пользователя, например transcriber, и выдайте ему только нужные права. После этого добавьте сервисную учетную запись:
insert into service_accounts
(name, client_id, scopes, enabled, created_at)
values
('transcriber', <client_id>, '["conference:join","media:render","chat:write"]', 1, strftime('%s','now'));
При постановке CAN job transcriber.start без payload.auth сервер:
- Находит
service_accounts.name = 'transcriber'или имя изpayload.service_account. - Проверяет, что запись включена и не истекла.
- Выпускает короткий access JWT для связанного пользователя.
- Добавляет токен в
payload.auth. - Отправляет задание online worker'у
role=transcriber.
Пример CAN job:
{
"job_type": "transcriber.start",
"target_role": "transcriber",
"required_capability": "speech_to_text",
"payload": {
"server_url": "https://join.videograce.ru",
"conference_tag": "teamsink",
"source": {
"type": "conference_audio"
},
"language": "ru",
"window_sec": 4
}
}
Пароль сервисного пользователя в CAN job передавать не нужно.
Эксплуатационные рекомендации
- Храните
JwtSecretиVG_CAN_SERVICE_TOKENкак разные секреты. - Не используйте учетную запись owner/admin для сервисов транскрибации и записи.
- Для каждого класса сервисов создавайте отдельную service account.
- После изменения
JwtSecretперезапустите сервер и проверьте повторный вход web/PWA клиентов. - Для резервного копирования сохраняйте основную БД: без нее refresh token и service account state будут потеряны.