Справочник
Сводка по единой авторизации и MCP-федерации: переменные, TTL, схема данных, поведение при отзыве доступа и карта кода в api-new.
Переменные окружения платформы
SSO
| Переменная | По умолчанию | Смысл |
|---|---|---|
SSO_CODE_TTL_SEC | 60 | Время жизни одноразового sso_code |
SSO_REFRESH_EXPIRE | 30d | Срок SERVICE_REFRESH-токена сервиса |
Token introspection
| Переменная | По умолчанию | Смысл |
|---|---|---|
AUTH_VALIDATE_VERIFY_SIGNATURE | true | Проверять подпись JWT в /auth/validate. Выключать без причины не нужно: стоит ~5 мкс и страхует от компрометации Redis |
AUTH_VALIDATE_VERDICT_TTL_MS | 5000 | TTL внутреннего LRU позитивных вердиктов |
AUTH_VALIDATE_VERDICT_MAX_ENTRIES | 10000 | Размер этого LRU |
MCP-федерация
| Переменная | По умолчанию | Смысл |
|---|---|---|
MCP_CANONICAL_URL | http://localhost:3636 | Канонический адрес MCP платформы |
MCP_FEDERATION_REFRESH_SEC | 300 | Период пересборки федеративного снапшота. 0 выключает федерацию целиком |
MCP_FEDERATION_CALL_TIMEOUT_MS | 30000 | Жёсткий потолок таймаута федеративного вызова |
MCP_FEDERATION_MAX_REQUEST_BYTES | 262144 | Максимум тела исходящего вызова (256 КБ) |
MCP_FEDERATION_MAX_RESPONSE_BYTES | 5000000 | Максимум ответа сервиса (5 МБ) |
MCP_FEDERATION_MAX_CONCURRENT | 16 | Одновременных федеративных вызовов |
MCP_FEDERATION_MAX_QUEUE | 200 | Длина очереди ожидания слота |
Сборка списка тулов живёт по собственным, более жёстким лимитам: таймаут 10 с, запрос ≤ 16 КБ, ответ ≤ 2 МБ.
Сроки жизни
| Что | Сколько |
|---|---|
sso_code | 60 с, одноразовый (атомарный GETDEL в Redis) |
ACCESS-токен из /sso/token | 60 с (плюс эфемерная сессия на тот же срок) |
| Синтетический ACCESS для федеративного вызова | 60 с, сессия гасится сразу после ответа |
SERVICE_REFRESH | 30 дней, с ротацией на каждом обмене |
| Кэш реестра сервисных кредов на платформе | 60 с, сбрасывается при правке строки через админ-ручки |
| Федеративный снапшот тулов | Пересобирается раз в 300 с |
Рекомендуемый кэш /auth/validate на стороне сервиса | 30 с позитив, 5 с негатив |
Лимиты запросов
| Ручка | Лимит |
|---|---|
POST /sso/grant | 30 запросов в минуту |
POST /sso/token | 60 запросов в минуту на сервис (ключ — X-Service-Client, при его отсутствии IP) |
Схема данных
external_tools — реестр сервисов
Поля единой авторизации, добавленные миграцией 20260913100000-unified-auth-registry:
| Колонка | Тип | Назначение |
|---|---|---|
sso_enabled | boolean, not null, default false | Разрешён ли браузерный SSO |
sso_redirect_uris | text[] (varchar 2048) | Allowlist префиксов возврата |
service_secret_hash | varchar(64) | sha256 сервисного секрета |
mcp_url | varchar(2048) | Endpoint MCP-канала |
mcp_timeout_ms | integer, not null, default 30000 | Таймаут федеративного вызова |
Рядом живут более ранние code, is_active, mcp_enabled, permission_key и MF-поля.
service_refresh_tokens — refresh-токены сервисов
| Колонка | Тип | Назначение |
|---|---|---|
_id | uuid PK | |
user_id | uuid → users._id, on delete cascade | Владелец |
service_code | varchar(64) | Код сервиса из реестра |
token_sha256 | varchar(64), unique | Хеш токена — сам токен не хранится |
jti | uuid | Идентификатор выпуска |
rotated_from_jti | uuid, null | Предыдущее звено цепочки ротации |
expires_at | timestamptz | Срок |
revoked_at | timestamptz, null | Отзыв: ротацией, ревокацией или обнаружением повтора |
last_used_at | timestamptz, null | Последний обмен |
Индексы: (user_id, service_code) и (jti).
permissions.allowed_urls — права на федеративные тулы
Колонка — массив текста, каждый элемент JSON-строка:
{"url":"ext/idea_calc/calc_unit_economics","httpMethod":"POST"}Та же форма используется для обычных роутов платформы (без префикса /api/v1), поэтому федеративные тулы проходят существующую проверку прав без исключений.
Матрица отзыва доступа
| Событие | ACCESS пользователя | SERVICE_REFRESH сервисов |
|---|---|---|
| Обычный logout | Гаснет (session_revoked) | Живёт |
| «Выйти везде» | Гаснут все | Отзываются |
| Смена пароля | Гаснут | Отзываются |
| Восстановление пароля по ссылке | Гаснут | Отзываются |
| Деактивация пользователя | valid: false | /sso/token → access_denied |
| Обнаружен повтор refresh | — | Отзывается вся цепочка пользователь + сервис |
| Удаление строки сервиса из реестра | — | Обмен перестаёт работать: кред больше не проходит |
Изменение прав пользователя токены не отзывает — оно повышает epoch, по которому сервисы сбрасывают свои кэши.
Коды ошибок
POST /auth/validate
Всегда 200. Причина отказа — в reason: missing_authorization, unsupported_authorization_type, invalid_or_expired, wrong_token_type, user_pending_confirmation, session_revoked, validation_unavailable.
POST /sso/grant
200 — выдан redirect; 401 — нет валидного пользовательского токена; 404 Unknown SSO client; 403 redirect_uri is not allowed for this client.
POST /sso/token
200 — пара токенов; 401 invalid_client; 403 unauthorized_client; 403 access_denied; 400 invalid_request; 400 invalid_grant (истёкший или использованный код, чужой клиент, неизвестный или повторно использованный refresh).
Федеративный вызов тула
Возвращается пользователю как результат тула с isError: true и телом {"service":"<code>","error":{"code":…,"message":…}}: request_failed, request_too_large, response_too_large, invalid_json, http_error, overloaded, internal.
Админ-ручки реестра
201 / 204 / 200 при успехе; 400 — неполная строка или неизвестные тулы; 404 — строки нет; 409 — дубль code/permissionKey либо вызов не от админа; 502 — MCP-канал сервиса недоступен.
Карта кода в api-new
| Файл | Что внутри |
|---|---|
core/services/v1/auth/auth.service.js | POST /auth/validate, сборка вердикта, include-гейт |
core/services/v1/auth/lib/validateFastPath.js | Разбор include, дешёвые отказы, LRU вердиктов |
core/services/v1/auth/lib/serviceClients.js | Проверка сервисного креда, кэш реестра на 60 с |
core/services/v1/sso/sso.service.js | POST /sso/grant, POST /sso/token, ротация и обнаружение повтора |
core/services/v1/sso/lib/ssoHelpers.js | Сверка redirect_uri, сборка redirect, вердикт по refresh |
core/services/v1/sso/lib/ssoCodeStore.js | Одноразовые коды в Redis |
core/services/v1/mcp/lib/federatedAggregator.js | Опрос каналов, префиксы имён, сборка снапшота |
core/services/v1/mcp/lib/federatedPermissions.js | Каталог тулов и отбор url для пермишена |
core/services/v1/mcp/lib/toolsCaller.js | callFederatedTool, синтетический ACCESS |
core/services/v1/mcp/lib/mcpHttp.js | HTTP JSON-RPC с потолками запроса и ответа |
core/services/v1/mcp/lib/concurrencyGate.js | Семафор исходящих вызовов |
core/services/v1/admins/admin.service.js | Админ-ручки реестра, каталога тулов и сборки пермишена |
core/common/logic/revokeServiceRefreshTokens.js | Отзыв сервисных refresh при смене пароля |
migrations/20260913100000-unified-auth-registry.js | Поля реестра и таблица service_refresh_tokens |
Юнит-тесты лежат рядом: core/tests/unit/logic/{validateFastPath,ssoHelpers,federatedAggregator,federatedPermissions,mcpHttp,concurrencyGate}.unit.test.js.