- AGENT-GUIDE.md: убран IP ВМ, HTTP→HTTPS - copilot-instructions.md: Files/token.txt→.env.example - keycloak-auth-reference.md: убраны реальные client_id, URL gateway, email - deploy-keycloak.md: реальные параметры заменены на шаблоны - .env.example: русские значения→шаблоны - README.md: порт 3000, multi-company пример под mock
6.7 KiB
6.7 KiB
Keycloak Auth Reference — консолидированная справка
Обновлено: 2026-06-02
Файл-ориентир. Править по мере уточнения у DevOps и продвижения проекта.
1. Keycloak-эндпоинты
Realm: cloud на keycloak.nubes.ru
| Назначение | URL |
|---|---|
| Authorization | https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/auth |
| Token exchange | https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/token |
| JWKS (сертификаты) | https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/certs |
| Logout | https://keycloak.nubes.ru/realms/cloud/protocol/openid-connect/logout |
2. Зарегистрированное приложение (OAuth client)
client_id — выдаётся DevOps при регистрации приложения в Keycloak.
3. Схема аутентификации: Authorization Code Flow
1. Браузер → /login (приложение)
2. Приложение → 302 → Keycloak /auth?client_id=...&scope=openid&redirect_uri=...&state=...
3. Пользователь вводит логин/пароль в Keycloak
4. Пользователь вводит OTP (MFA)
5. Keycloak → 302 → /callback?code=...&state=...
6. Приложение → POST /token (code → access_token + refresh_token + id_token)
7. Валидация JWT через JWKS (RS256)
8. Извлечение claims → req.user → сессия
4. Получение токена через API Gateway (альтернативный путь)
Если в инфраструктуре есть API Gateway, код обменивается не напрямую в Keycloak, а через него:
POST <url API Gateway>/token
Content-Type: application/json
Body: {"code": "<authorization_code>"}
5. JWT-токены
5.1. Пример структуры JWT (deprecated)
iss: https://<issuer>/...
aud: <audience>
sub: <email>
name: <ФИО пользователя>
email: <email пользователя>
exp: <timestamp>
scope: openid
token_type: Bearer
Claims (массив):
""""wz03709-shturval-admin-iot-naeel— namespace в k8s (Fission)wz03709-shturval-admin-naeel-test-3— ещё один namespace
⚠️
ClientIDв этом токене отсутствует — это другой issuer (auth.k8s.ngcloud.ru), не Keycloak.
5.2. Токен из HAR (deck-test)
| Поле | Значение |
|---|---|
iss |
auth-api |
ClientID |
WZ01325 |
company_id |
3e64aac6-dcfc-4082-88dc-da19c86555a5 |
company_name |
Тест |
login |
tazet@narod.ru |
firstname |
Наиль |
lastname |
Тазетдинов |
email |
tazet@narod.ru |
5.3. Целевой формат токена (из ТЗ)
| Claim | Назначение |
|---|---|
ClientID |
Идентификатор компании (WZ-номер) |
company_id |
UUID компании |
company_name |
Название компании |
email |
Email пользователя (для аудита) |
groups |
? (пока null) |
roles |
? (пока null) |
6. Роли
| Роль | ClientID | Права |
|---|---|---|
| Администратор | WZ01112 |
Все записи, просмотр аудита, экспорт |
| Клиент | любой другой WZ-номер | Только свои записи |
Как именно ClientID попадает в токен — через группы Keycloak или маппер — требует уточнения у DevOps.
7. Реализация в коде
src/auth.js — два режима
| Режим | Условие | Как работает |
|---|---|---|
| OIDC | KC_CLIENT_ID + KC_CLIENT_SECRET заданы |
Authorization Code Flow, JWKS-валидация |
| Mock | KC_CLIENT_ID пусто |
Локальная RSA-пара, JWT из MOCK_USERS |
src/config.js — Mock-пользователи
MOCK_USERS = [
{ clientId: 'WZ01325', companyName: 'Тест', email: 'tazet@narod.ru' },
{ clientId: 'WZ01112', companyName: 'Нубес', email: 'admin@nubes.ru' }
]
Два слоя аутентификации
| Слой | Механизм | Где |
|---|---|---|
| UI (EJS) | Session cookie + PostgreSQL session store | /, /admin, /entries |
| REST API | Bearer JWT (всегда проверяется явно) | /api/v1/* |
Dev-backdoor
DEV_MODE=trueилиDEV_SECRET→/dev-login— выбор любого пользователя в обход OIDC/mock
8. Переменные окружения
# Auth
DEV_MODE=true
JWT_ISSUER=mock-auth-api
ADMIN_CLIENT_ID=WZ01112
# OIDC (production)
KC_BASE_URL=https://keycloak.nubes.ru/realms/cloud
KC_CLIENT_ID=
KC_CLIENT_SECRET=
APP_URL=http://localhost:3000
# Session
SESSION_SECRET=<обязателен в prod>
9. Открытые вопросы (к DevOps)
| # | Вопрос | Статус |
|---|---|---|
| 1 | Где брать client_id и client_secret для регистрации приложения в Keycloak? |
🔴 |
| 2 | Какой URL JWKS? auth-api или keycloak.nubes.ru? |
🔴 |
| 3 | Когда заполняются claims.groups и claims.roles? (пока null) |
🔴 |
| 4 | Как выглядит токен, если у пользователя несколько компаний? Массив ClientID? |
🔴 |
| 5 | Есть ли в Keycloak понятие admin-роли? В каком claim? | 🔴 |
| 6 | Redirect URI: https://white.nodejsk8s.dev.nubes.ru/callback — OK? |
🔴 |
| 7 | Кто потребитель /export? Какие IP/подсети для allowlist? |
🔴 |
| 8 | Формат jsonEnv — пример правильного? |
🔴 |
10. Исходные файлы
| Файл | Содержание |
|---|---|
docs/ТЗ.md |
Техническое задание |
docs/ТЗ-реализация.md |
Карта реализации требований |
docs/questions-devops.md |
Вопросы к DevOps |
research/auth-flow.md |
Детальное исследование OIDC-flow |
research/payg-sso/ |
CF-эталон (OAuth2 + JWT RS256) |
Files/token.txt |
Реальный токен из test-окружения |
Files/nubes_login.har |
HAR трассировка login-сессии deck-test |
src/auth.js |
Основной модуль аутентификации |
src/config.js |
Конфигурация и mock-пользователи |