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

Управление пользователями

AppSec.AIGate использует ролевую модель доступа (RBAC) с интеграцией через Keycloak и OAuth2 Proxy. В этом разделе описано, как работает аутентификация, какие роли существуют, как управлять пользователями через UI и API, а также как настроить мультитенантную изоляцию.

Архитектура аутентификации

Система аутентификации состоит из трёх компонентов, работающих совместно:

Браузер (Admin UI)
┌──────────────────────────────┐
│  OAuth2 Proxy (порт 4180)    │  ← Проверяет cookie-сессию
│                              │  ← Если нет сессии → redirect на Keycloak
│  Cookie: _oauth2_proxy=...   │  ← Извлекает из токена: user, email, groups, tenant_id
│                              │  ← Устанавливает X-Forwarded-* заголовки
└──────────────┬───────────────┘
               │ + X-Forwarded-User
               │ + X-Forwarded-Email
               │ + X-Forwarded-Groups
               │ + X-Forwarded-Tenant-Id
┌──────────────────────────────┐
│  Admin API (порт 8001)       │  ← Читает X-Forwarded-* заголовки
│                              │  ← Создаёт объект CurrentUser
│  RBAC middleware:            │  ← require_role("admin") → проверка groups
│  require_role(role)          │  ← Запись в audit log: user, action, resource
│  require_tenant_access(tid)  │
└──────────────────────────────┘
┌──────────────────────────────┐
│  Keycloak (порт 8080)        │  ← Identity Provider (OpenID Connect)
│                              │  ← Хранит: пользователей, роли, tenant_id
│  Realm: llm-firewall         │  ← Выдаёт JWT access token
│  Client: admin-api           │  ← Protocol Mapper: tenant_id → JWT claim
└──────────────────────────────┘

Поток аутентификации (Production):

  1. Пользователь открывает Admin UI в браузере.
  2. OAuth2 Proxy проверяет наличие cookie _oauth2_proxy.
  3. Если cookie отсутствует или истёк — OAuth2 Proxy перенаправляет на Keycloak.
  4. Пользователь вводит логин/пароль на странице Keycloak.
  5. Keycloak выдаёт JWT access token с claims: preferred_username, email, groups, tenant_id.
  6. OAuth2 Proxy создаёт cookie-сессию и перенаправляет обратно в Admin UI.
  7. При каждом запросе к Admin API OAuth2 Proxy добавляет заголовки X-Forwarded-* из JWT.
  8. Admin API извлекает заголовки, создаёт объект CurrentUser, проверяет роль и тенант.

Режимы работы

Система поддерживает два режима аутентификации, управляемых переменной окружения OAUTH2_PROXY_ENABLED.

Режим разработки (Development)

Переменная:  OAUTH2_PROXY_ENABLED=false
Запуск:      make dev (в каталоге code/compose)

В режиме разработки аутентификация полностью отключена. Все запросы к Admin API выполняются от имени встроенного пользователя:

Поле Значение
username dev-user
email dev@example.com
groups (роли) ["admin", "user"]
tenant_id dev-test

Особенности:

  • Keycloak и OAuth2 Proxy не требуются — можно обращаться напрямую к Admin API (порт 8001).
  • Все операции разрешены (роль admin).
  • Swagger UI доступен без авторизации: http://localhost:8001/docs.
  • Аудит записывает действия от dev-user.

Когда использовать: Локальная разработка, тестирование, демонстрации. Не использовать в production — любой пользователь с сетевым доступом получит полный контроль над системой.

Продуктовый режим (Production)

Переменная:  OAUTH2_PROXY_ENABLED=true (по умолчанию)
Запуск:      make prod (в каталоге code/compose)

В продуктовом режиме все запросы к Admin API должны содержать заголовки X-Forwarded-*, установленные OAuth2 Proxy. Без этих заголовков API вернёт HTTP 401.

Заголовки аутентификации:

Заголовок Источник Описание
X-Forwarded-User JWT preferred_username Имя пользователя
X-Forwarded-Email JWT email Email пользователя
X-Forwarded-Groups JWT groups Роли через запятую: "admin,viewer"
X-Forwarded-Preferred-Username JWT preferred_username Предпочтительное имя
X-Forwarded-Tenant-Id JWT tenant_id (custom claim) Идентификатор тенанта

Особенности:

  • Прямой доступ к Admin API (порт 8001) без OAuth2 Proxy вернёт 401.
  • Все операции проверяются через RBAC (роль из X-Forwarded-Groups).
  • Аудит записывает реальные имя и email пользователя.
  • Cookie-сессия OAuth2 Proxy — HTTP-only, Secure (при HTTPS).

Роли и полномочия

В системе определены четыре роли. Каждый пользователь может иметь одну или несколько ролей.

admin

Назначение:  Полный контроль над системой
Типичный пользователь: CISO, DevSecOps-инженер, администратор платформы

Роль admin даёт неограниченный доступ ко всем функциям системы. Только администраторы могут:

  • Управлять пользователями — создавать, удалять, блокировать учётные записи, назначать роли.
  • Удалять ресурсы — провайдеров, профили, контентные политики, экспортеры (безвозвратное удаление).
  • Просматривать аудит — журнал всех действий всех пользователей (см. Аудит и журнал действий).
  • Настраивать retention — политики хранения данных (см. Настройки хранения данных).
  • Управлять всеми ресурсами — создавать, редактировать, активировать провайдеров, профили, политики и экспортеры.

Рекомендация: Минимизируйте количество пользователей с ролью admin. Для повседневных операций (настройка профилей, реагирование на инциденты) используйте роль operator.

operator

Назначение:  Операционное управление безопасностью
Типичный пользователь: SOC-аналитик, AppSec-инженер, DevOps

Роль operator предназначена для ежедневной работы с системой. Операторы могут:

  • Создавать и редактировать — провайдеров, профили безопасности, контентные политики, экспортеры.
  • Генерировать отчёты — создавать и скачивать отчёты о соответствии.
  • Анализировать события — просматривать события безопасности, фильтровать по типам и времени.
  • Мониторить Dashboard — видеть статистику, графики, последние инциденты.

Ограничения:

  • Не может удалять провайдеров, профили, политики (только admin).
  • Не может управлять пользователями — создавать, удалять, назначать роли.
  • Не может просматривать аудит — журнал действий доступен только admin.
  • Не может изменять retention settings — только admin.

viewer

Назначение:  Только просмотр (read-only)
Типичный пользователь: Аудитор, менеджер, внешний проверяющий

Роль viewer ограничена чтением данных без возможности изменений:

  • Просматривать — все провайдеры, профили, политики, экспортеры, события, Dashboard.
  • Скачивать отчёты — ранее сгенерированные отчёты (PDF, CSV).

Ограничения:

  • Не может создавать, редактировать или удалять любые ресурсы.
  • Не может генерировать отчёты (только скачивать существующие).
  • Не может управлять пользователями.
  • Не может просматривать аудит и retention settings.

Когда использовать: Для предоставления доступа внешним аудиторам или руководству без риска случайного изменения конфигурации.

super-admin

Назначение:  Межтенантный доступ (мультитенантные развёртывания)
Типичный пользователь: Администратор платформы в SaaS/MSP-сценарии

Роль super-admin расширяет admin возможностью работать с данными всех тенантов. Обычный admin видит только ресурсы своего тенанта (определяемого по tenant_id в JWT). super-admin обходит проверку тенанта и может:

  • Просматривать провайдеров, профили и события всех организаций.
  • Управлять пользователями всех тенантов.
  • Генерировать кросстенантные отчёты.

Когда использовать: Только в мультитенантных развёртываниях, где одна инсталляция AppSec.AIGate обслуживает несколько организаций.

Матрица прав доступа (RBAC)

Полная таблица разрешений по ролям:

Ресурс / Операция admin operator viewer super-admin
Providers
Просмотр списка и деталей ✓ (все тенанты)
Создание
Редактирование
Удаление
Profiles
Просмотр списка и деталей ✓ (все тенанты)
Создание
Редактирование / активация
Удаление / архивация
Content Policies
Просмотр ✓ (все тенанты)
Создание / редактирование
Удаление
Exporters
Просмотр ✓ (все тенанты)
Создание / редактирование
Удаление
Reports
Генерация (создание)
Скачивание
Удаление
Security Events
Просмотр и фильтрация ✓ (все тенанты)
Dashboard
Просмотр метрик и графиков ✓ (все тенанты)
Audit Log
Просмотр журнала действий
Retention Settings
Просмотр и изменение
Users
Просмотр списка
Создание / редактирование
Удаление / блокировка
Назначение ролей

Правило приоритета ролей: Если пользователю назначено несколько ролей (например, admin и viewer), применяется максимальный уровень привилегий. Проверка выполняется через has_any_role() — достаточно наличия хотя бы одной роли с необходимым уровнем доступа.

Управление пользователями через Admin UI

Страница Users доступна только пользователям с ролью admin по адресу /users в Admin UI.

Список пользователей

На странице отображается таблица со всеми зарегистрированными пользователями:

Столбец Описание
Username Имя пользователя (уникальное)
Email Электронная почта
Имя / Фамилия ФИО пользователя
Статус Бейдж: «Активный» (зелёный) или «Заблокирован» (красный)
Email Бейдж: «✓ Подтверждён» или «⏳ Не подтверждён»
Действия Кнопки: просмотр, редактирование, управление ролями, блокировка/разблокировка, удаление

Создание пользователя

  1. Нажмите кнопку «+ Добавить пользователя» в правом верхнем углу.
  2. Заполните форму:

    Поле Обязательное Валидация Описание
    Username Да Мин. 3 символа, уникальное Логин для входа в систему
    Email Да RFC 5322, уникальный Email (используется для уведомлений и восстановления пароля)
    Пароль Да Мин. 8 символов Начальный пароль пользователя
    Имя Да Имя пользователя
    Фамилия Да Фамилия пользователя
  3. Нажмите «Создать».

  4. Пользователь создаётся в Keycloak с enabled=true и emailVerified=false.
  5. Роли не назначены — после создания необходимо явно назначить роль (см. Управление ролями).

Важно

Пользователь без назначенной роли сможет авторизоваться в Keycloak, но все запросы к Admin API будут возвращать HTTP 403 (нет разрешённой роли в X-Forwarded-Groups).

Редактирование пользователя

  1. Нажмите иконку карандаша (✏️) в строке пользователя.
  2. Измените нужные поля: username, email, имя, фамилия.
  3. Нажмите «Сохранить».

Ограничения:

  • Пароль нельзя изменить через Admin UI — используйте Keycloak Admin Console (http://localhost:8080) или функцию сброса пароля.
  • tenant_id изменяется только через Keycloak Admin Console (атрибут пользователя).

Управление ролями

  1. Нажмите иконку щита (🛡) в строке пользователя — откроется модальное окно «Manage Roles».
  2. В окне отображаются текущие роли пользователя с кнопками:

    • «Назначить» — добавить роль (выбор из: admin, operator, viewer, super-admin).
    • «Отозвать» — убрать роль.
  3. Изменения применяются немедленно — при следующем запросе OAuth2 Proxy получит обновлённый токен с новыми ролями.

Пример: Новый SOC-аналитик — создайте пользователя, назначьте роль operator. Он получит доступ к Dashboard, событиям, профилям и политикам, но не сможет удалять ресурсы или управлять пользователями.

Блокировка / разблокировка

  1. Нажмите иконку питания (⏻) в строке пользователя.
  2. Система попросит подтверждение.
  3. Заблокированный пользователь (enabled=false) не сможет авторизоваться в Keycloak — его текущая сессия продолжит работать до истечения TTL cookie OAuth2 Proxy.

Когда использовать: Временная блокировка при расследовании инцидента, увольнение сотрудника. Для немедленного прекращения доступа также очистите сессии в Keycloak Admin Console.

Удаление пользователя

  1. Нажмите иконку корзины (🗑) в строке пользователя.
  2. Подтвердите удаление в диалоговом окне.
  3. Пользователь безвозвратно удаляется из Keycloak.

Внимание

Удаление необратимо. Аудитные записи, созданные этим пользователем, сохраняются (содержат имя и email на момент действия), но учётная запись восстановлению не подлежит — потребуется создать заново.

API управления пользователями

Все операции с пользователями доступны через REST API. Все эндпоинты требуют роль admin.

Список пользователей

curl -s http://localhost:8001/api/v1/users \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

Ответ (HTTP 200):

[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "username": "john.doe",
    "email": "john@company.com",
    "firstName": "John",
    "lastName": "Doe",
    "enabled": true,
    "emailVerified": true,
    "createdTimestamp": 1710345600000
  },
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
    "username": "jane.smith",
    "email": "jane@company.com",
    "firstName": "Jane",
    "lastName": "Smith",
    "enabled": true,
    "emailVerified": false,
    "createdTimestamp": 1710432000000
  }
]

Поля ответа:

Поле Тип Описание
id строка (UUID) Уникальный идентификатор пользователя в Keycloak
username строка Имя пользователя (логин)
email строка Электронная почта
firstName строка Имя
lastName строка Фамилия
enabled boolean true — активен, false — заблокирован
emailVerified boolean true — email подтверждён
createdTimestamp число (ms) Время создания (Unix timestamp в миллисекундах)

Получение пользователя по ID

curl -s http://localhost:8001/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

Ответ (HTTP 200): Объект пользователя (аналогично элементу из списка).

Ошибка (HTTP 404): Пользователь с указанным ID не найден.

Создание пользователя

curl -s -X POST http://localhost:8001/api/v1/users \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  -d '{
    "username": "new.analyst",
    "email": "analyst@company.com",
    "password": "SecureP@ss2026",
    "first_name": "Алексей",
    "last_name": "Петров"
  }' | jq .

Тело запроса:

Поле Тип Обязательное Валидация
username строка Да Мин. 3 символа, уникальное
email строка Да RFC 5322, уникальный
password строка Да Мин. 8 символов
first_name строка Да Непустая строка
last_name строка Да Непустая строка

Ответ (HTTP 201): ID созданного пользователя.

Ошибки:

HTTP Причина
400 Невалидные данные (короткий username, невалидный email)
409 Username или email уже существует
403 Вызывающий не имеет роли admin

Важно

Пользователь создаётся без ролей. После создания назначьте роль через отдельный вызов (см. Получение ролей пользователя).

Редактирование пользователя

curl -s -X PUT http://localhost:8001/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  -d '{
    "email": "new-email@company.com",
    "first_name": "Алексей",
    "last_name": "Иванов"
  }' | jq .

Тело запроса: Все поля опциональны — передайте только те, которые хотите изменить:

Поле Тип Описание
username строка Новое имя пользователя
email строка Новый email
first_name строка Новое имя
last_name строка Новая фамилия

Ответ (HTTP 200): Обновлённый объект пользователя.

Блокировка / разблокировка

# Заблокировать
curl -s -X POST http://localhost:8001/api/v1/users/a1b2c3d4.../disable \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

# Разблокировать
curl -s -X POST http://localhost:8001/api/v1/users/a1b2c3d4.../enable \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

Ответ (HTTP 200): Объект пользователя с обновлённым полем enabled.

Удаление пользователя

curl -s -X DELETE http://localhost:8001/api/v1/users/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin"

Ответ (HTTP 204): Пользователь удалён (нет тела ответа).

Внимание

Удаление безвозвратно. Keycloak не поддерживает soft delete пользователей.

Получение ролей пользователя

curl -s http://localhost:8001/api/v1/users/a1b2c3d4.../roles \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

Ответ (HTTP 200):

[
  {
    "id": "role-uuid-1",
    "name": "operator",
    "composite": false,
    "clientRole": false,
    "containerId": "llm-firewall"
  }
]

Назначение роли

curl -s -X POST http://localhost:8001/api/v1/users/a1b2c3d4.../roles \
  -H "Content-Type: application/json" \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  -d '{"role_name": "operator"}'

Допустимые значения role_name: "admin", "operator", "viewer", "super-admin".

Ответ (HTTP 200): Роль назначена.

Ошибки:

HTTP Причина
400 Невалидное имя роли
404 Пользователь или роль не найдены
409 Роль уже назначена

Отзыв роли

curl -s -X DELETE http://localhost:8001/api/v1/users/a1b2c3d4.../roles/operator \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin"

Ответ (HTTP 204): Роль отозвана.

Список всех ролей

curl -s http://localhost:8001/api/v1/roles \
  -H "X-Forwarded-User: admin" \
  -H "X-Forwarded-Email: admin@company.com" \
  -H "X-Forwarded-Groups: admin" \
  | jq .

Ответ (HTTP 200):

[
  {"id": "...", "name": "admin", "description": "Full system access..."},
  {"id": "...", "name": "operator", "description": "Operational/Security team..."},
  {"id": "...", "name": "viewer", "description": "Read-only access..."},
  {"id": "...", "name": "super-admin", "description": "Cross-tenant access..."}
]

Keycloak интеграция

Начальная конфигурация

При первом запуске в production-режиме (make prod) автоматически выполняется инициализация Keycloak через контейнер keycloak-init:

  1. Создание realm llm-firewall с настройками:

    • Вход по email разрешён.
    • Дублирование email запрещено.
    • Защита от brute force включена.
    • Сброс пароля включён.
    • Редактирование username отключено.
  2. Создание ролей в realm: admin, operator, viewer, super-admin.

  3. Создание OAuth2 клиента admin-api:

    • Тип: public client (без client secret).
    • Протокол: OpenID Connect.
    • Redirect URIs: http://localhost:4180/*, http://localhost:4180/oauth2/callback.
    • Standard flow + Direct access grants.
  4. Настройка Protocol Mapper tenant-id-mapper:

    • Маппит пользовательский атрибут tenant_id → JWT claim tenant_id.
    • Включён в: ID token, access token, userinfo.
  5. Создание начального администратора:

    • Username: значение ADMIN_USER_EMAIL (по умолчанию admin@llm-firewall.local).
    • Пароль: значение ADMIN_USER_PASSWORD (по умолчанию AdminPassword123!).
    • Атрибут: tenant_id: ["tenant-admin"].
    • Роль: admin.

Важно

Смените пароль начального администратора сразу после первого входа!

Настройка для production

Для production-развёртывания рекомендуется изменить следующие параметры:

Параметр Где Значение по умолч. Рекомендация
KEYCLOAK_ADMIN_PASSWORD docker-compose admin Сложный пароль (16+ символов)
ADMIN_USER_PASSWORD docker-compose AdminPassword123! Сложный пароль
ADMIN_USER_EMAIL docker-compose admin@llm-firewall.local Реальный email
SSL Required Keycloak Admin Console none all (принудительный HTTPS)
Redirect URIs Keycloak Admin Console http://localhost:4180/* Реальный домен: https://admin.company.com/*

Дополнительные политики паролей

Базовые требования к паролям (минимум 8 символов) можно ужесточить через Keycloak Admin Console:

  1. Откройте http://localhost:8080 → Realm llm-firewallAuthenticationPassword Policy.
  2. Добавьте правила:
Правило Описание Рекомендация
Minimum Length Минимальная длина 12+ символов
Uppercase Characters Обязательная заглавная буква 1+
Lowercase Characters Обязательная строчная буква 1+
Digits Обязательная цифра 1+
Special Characters Обязательный спецсимвол 1+
Not Username Пароль ≠ username Включить
Password History Запрет повторных паролей 5 последних
Hashing Algorithm Алгоритм хеширования pbkdf2-sha256 (по умолч.)

Мультитенантная изоляция

В мультитенантных развёртываниях каждый пользователь принадлежит к одному тенанту. Изоляция данных обеспечивается на уровне API.

Как работает изоляция

Пользователь "john" (tenant_id: "company-a")
    ▼ GET /api/v1/providers
Admin API: require_tenant_access("company-a", current_user)
    ├─ john.tenant_id == "company-a" → ✓ Доступ разрешён
    │  → Возвращаются только провайдеры company-a
    └─ john пытается GET /api/v1/providers?tenant_id=company-b
       → HTTP 403: Access denied

Настройка tenant_id

Tenant ID назначается пользователю как атрибут в Keycloak:

  1. Откройте Keycloak Admin Console → Users → выберите пользователя → Attributes.
  2. Добавьте атрибут:

    • Key: tenant_id.
    • Value: идентификатор тенанта (например, company-a).
  3. Сохраните.

Значение tenant_id автоматически попадает в JWT через Protocol Mapper tenant-id-mapper и передаётся в Admin API через заголовок X-Forwarded-Tenant-Id.

Super-admin и тенанты

Пользователь с ролью super-admin обходит проверку тенанта (can_access_tenant() всегда возвращает true). Это позволяет:

  • Просматривать ресурсы всех тенантов в едином интерфейсе.
  • Управлять пользователями из разных организаций.
  • Генерировать кросстенантные отчёты.

Аудит действий пользователей

Все изменения, выполняемые пользователями, записываются в журнал аудита (подробнее см. Аудит и журнал действий). Для каждого действия фиксируется:

Поле Описание Пример
user_id Имя пользователя john.doe
user_email Email john@company.com
user_role Роль на момент действия admin
action HTTP-метод POST, PUT, DELETE
resource_type Тип ресурса providers, profiles, users
resource_id ID ресурса a1b2c3d4-...
request_body Тело запроса (с редакцией) {"username": "new.user", "password": "***REDACTED***"}
response_status HTTP-статус ответа 201, 403
timestamp Время действия 2026-03-13T14:30:00Z

Редакция чувствительных данных: Поля password, secret, token, api_key в теле запроса автоматически заменяются на ***REDACTED*** перед записью в аудит.

Типичные конфигурации

Сценарий 1: Небольшая команда (5–10 человек)

1 admin    — DevSecOps lead (управление системой, пользователями)
2 operator — SOC-аналитики (настройка профилей, реагирование)
2 viewer   — Руководители (просмотр Dashboard, скачивание отчётов)

Один тенант (production), один набор провайдеров и профилей.

Сценарий 2: MSSP / SaaS (несколько организаций)

1 super-admin — Администратор платформы (все тенанты)
По каждой организации:
  1 admin    — IT-директор клиента
  2 operator — Аналитики клиента
  N viewer   — Аудиторы, менеджеры

Каждая организация — отдельный tenant_id. Super-admin управляет всеми.

Сценарий 3: Аудит / compliance-проверка

Создать временного пользователя с ролью viewer:
  username: auditor-2026-q1
  tenant_id: (того тенанта, который проверяется)

Аудитор получает read-only доступ к:
  - Dashboard (метрики)
  - Security Events (инциденты)
  - Reports (скачивание)

После проверки — заблокировать или удалить аккаунт.

Типичные проблемы и решения

Проблема: HTTP 401 при обращении к API

Симптом: Все запросы к Admin API возвращают HTTP 401.

Причины:

# Причина Диагностика Решение
1 Обращение напрямую к порту 8001 в prod-режиме curl http://localhost:8001/api/v1/providers → 401 Обращайтесь через OAuth2 Proxy (порт 4180) или передайте заголовки X-Forwarded-*
2 OAuth2 Proxy не запущен docker-compose ps oauth2-proxy docker-compose up -d oauth2-proxy
3 Cookie сессии истёк Очистите cookies, перелогиньтесь Keycloak session timeout (по умолч. 30 мин)

Проблема: HTTP 403 при попытке операции

Симптом: Пользователь авторизован, но получает 403 при попытке создать/удалить ресурс.

Причины:

# Причина Диагностика Решение
1 Недостаточные права роли viewer не может создавать ресурсы Назначьте роль operator или admin
2 Нет назначенных ролей Проверьте роли через API (см. Получение ролей пользователя) Назначьте роль (см. Назначение роли)
3 Тенант не совпадает tenant_id пользователя ≠ tenant_id ресурса Проверьте атрибут tenant_id в Keycloak

Проблема: начальный пароль не подходит

Симптом: Не удаётся войти под admin@llm-firewall.local с паролем по умолчанию.

Решение:

  1. Проверьте, что keycloak-init контейнер выполнился успешно:

    docker-compose logs keycloak-init | tail -20
    
  2. Если realm не создался (Keycloak не был готов) — перезапустите:

    docker-compose restart keycloak-init
    
  3. Для ручного сброса — через Keycloak Admin Console:

    http://localhost:8080 → admin/admin → Realm: llm-firewall → Users → admin → Credentials → Reset Password
    

Проблема: OAuth2 Proxy redirect loop

Симптом: Браузер зацикливается на странице логина Keycloak.

Причины:

# Причина Решение
1 Redirect URI не совпадает В Keycloak: Clients → admin-api → Valid Redirect URIs → добавьте ваш домен
2 Cookies не передаются (SameSite) Настройте HTTPS или --cookie-samesite=lax в OAuth2 Proxy
3 Keycloak не доступен Проверьте docker-compose ps keycloak, логи