> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bedolagam.ru/llms.txt
> Use this file to discover all available pages before exploring further.

# Управление доступом (RBAC + ABAC)

> Гибкая система ролей, разрешений и политик доступа для админ-панели Cabinet

## Обзор

Cabinet включает полноценную систему управления доступом, объединяющую два подхода:

* **RBAC** (Role-Based Access Control) — роли с набором разрешений и иерархией уровней
* **ABAC** (Attribute-Based Access Control) — политики с условиями (время, IP-адреса)

<Warning>
  Система RBAC/ABAC работает **только в Cabinet**. В Telegram-боте доступ администраторов по-прежнему определяется через `ADMIN_IDS`.
</Warning>

<CardGroup cols={3}>
  <Card title="Роли и разрешения" icon="shield-halved">
    30+ секций с индивидуальными действиями. Поддержка wildcard-паттернов.
  </Card>

  <Card title="Политики ABAC" icon="filter">
    Ограничение по времени суток, IP-адресам. Правило «запрет побеждает».
  </Card>

  <Card title="Журнал аудита" icon="clipboard-list">
    Неизменяемый лог всех действий администраторов с экспортом в CSV.
  </Card>
</CardGroup>

## Совместимость с legacy-доступом

Система полностью обратно совместима. Администраторы из `ADMIN_IDS` и `ADMIN_EMAILS` автоматически получают полный доступ (`*:*`) с синтетическим уровнем 1000 — выше любой RBAC-роли. RBAC-роли нужны только для дополнительных сотрудников с ограниченным доступом.

```env theme={null}
# Legacy-администраторы (обходят RBAC, получают все разрешения)
ADMIN_IDS=123456789,987654321
ADMIN_EMAILS=admin@example.com
```

## Роли

### Иерархия уровней

Каждая роль имеет уровень (level) от 0 до 999. Пользователь может управлять только ролями **ниже** своего уровня.

| Уровень | Назначение             | Пример                            |
| ------- | ---------------------- | --------------------------------- |
| 0       | Наблюдатель / аналитик | Просмотр статистики               |
| 1–499   | Поддержка, модераторы  | Работа с тикетами, пользователями |
| 500–998 | Менеджеры, тимлиды     | Управление тарифами, рассылками   |
| 999     | Суперадмин             | Полный доступ (`*:*`)             |
| 1000    | Legacy (ADMIN\_IDS)    | Автоматически, не редактируется   |

### Предустановленные шаблоны

При создании роли доступны готовые шаблоны разрешений:

| Шаблон         | Разрешения                                                       |
| -------------- | ---------------------------------------------------------------- |
| **Модератор**  | Пользователи, тикеты, бан-система, трафик                        |
| **Маркетолог** | Рассылки, промокоды, кампании, рекламные предложения, статистика |
| **Саппорт**    | Тикеты (чтение, ответ), пользователи (чтение)                    |

Шаблоны можно модифицировать — они задают начальный набор разрешений при создании роли.

### Системные роли

Роли с флагом `is_system=true` нельзя удалить. Последний суперадмин (level 999) защищён от удаления.

## Разрешения

### Формат

Каждое разрешение — строка в формате `секция:действие`:

```
users:read         — просмотр пользователей
users:edit         — редактирование профилей
users:*            — все действия с пользователями
*:*                — полный доступ ко всему
```

### Реестр разрешений

<AccordionGroup>
  <Accordion title="Пользователи (users)">
    `read` `edit` `block` `delete` `sync` `promo_group` `balance` `subscription` `send_offer` `referral`
  </Accordion>

  <Accordion title="Тикеты (tickets)">
    `read` `reply` `close` `settings`
  </Accordion>

  <Accordion title="Статистика (stats)">
    `read` `export`
  </Accordion>

  <Accordion title="Рассылки (broadcasts)">
    `read` `create` `edit` `delete` `send`
  </Accordion>

  <Accordion title="Тарифы (tariffs)">
    `read` `create` `edit` `delete`
  </Accordion>

  <Accordion title="Промокоды (promocodes)">
    `read` `create` `edit` `delete`
  </Accordion>

  <Accordion title="Промогруппы (promo_groups)">
    `read` `create` `edit` `delete`
  </Accordion>

  <Accordion title="Рекламные предложения (promo_offers)">
    `read` `create` `edit` `delete` `send`
  </Accordion>

  <Accordion title="Рекламные кампании (campaigns)">
    `read` `create` `edit` `delete` `stats`
  </Accordion>

  <Accordion title="Партнёры (partners)">
    `read` `approve` `revoke`
  </Accordion>

  <Accordion title="Выводы (withdrawals)">
    `read` `approve` `reject` `complete`
  </Accordion>

  <Accordion title="Платежи (payments)">
    `read`
  </Accordion>

  <Accordion title="Платёжные методы (payment_methods)">
    `read` `edit`
  </Accordion>

  <Accordion title="Серверы (servers)">
    `read` `create` `edit` `delete` `sync`
  </Accordion>

  <Accordion title="RemnaWave (remnawave)">
    `read` `sync` `manage`
  </Accordion>

  <Accordion title="Трафик (traffic)">
    `read`
  </Accordion>

  <Accordion title="Настройки (settings)">
    `read` `edit`
  </Accordion>

  <Accordion title="Роли (roles)">
    `read` `create` `edit` `delete` `assign`
  </Accordion>

  <Accordion title="Журнал аудита (audit_log)">
    `read` `export`
  </Accordion>

  <Accordion title="Прочее">
    `channels` · `ban_system` · `wheel` · `apps` · `email_templates` · `pinned_messages` · `updates` — у каждой секции свой набор действий
  </Accordion>
</AccordionGroup>

### Wildcard-сопоставление

Разрешения поддерживают glob-паттерны (fnmatch):

| Паттерн      | Что разрешает                 |
| ------------ | ----------------------------- |
| `users:read` | Только просмотр пользователей |
| `users:*`    | Все действия с пользователями |
| `*:read`     | Чтение во всех секциях        |
| `*:*`        | Полный доступ                 |

## Политики ABAC

Политики ABAC **дополняют** RBAC — они оцениваются после проверки разрешений роли. Политика может разрешить или **запретить** доступ с учётом условий.

### Эффекты

| Эффект  | Описание                                  |
| ------- | ----------------------------------------- |
| `allow` | Разрешить доступ (если RBAC уже разрешил) |
| `deny`  | Запретить доступ (приоритет выше allow)   |

**Правило:** если хотя бы одна политика deny совпала — доступ запрещён, независимо от разрешений роли.

### Условия

<CardGroup cols={2}>
  <Card title="Временной диапазон" icon="clock">
    Ограничение по времени (UTC). Формат: `{"start": "09:00", "end": "18:00"}`
  </Card>

  <Card title="IP-адреса" icon="network-wired">
    Белый список IP: `["192.168.1.0/24", "10.0.0.1"]`. Поддерживает CIDR и отдельные адреса.
  </Card>
</CardGroup>

### Примеры политик

**Запретить удаление пользователей в нерабочее время:**

```json theme={null}
{
  "name": "Запрет удаления после 18:00",
  "resource": "users",
  "actions": ["delete"],
  "effect": "deny",
  "conditions": {
    "time_range": { "start": "18:00", "end": "09:00" }
  }
}
```

**Доступ к админке только из офисной сети:**

```json theme={null}
{
  "name": "Только офис",
  "resource": "*",
  "actions": ["*"],
  "effect": "deny",
  "priority": 1000,
  "conditions": {
    "ip_whitelist": ["203.0.113.0/24", "198.51.100.1"]
  }
}
```

### Приоритет

Политики оцениваются в порядке `priority` (больше = раньше). Первая совпавшая deny-политика немедленно блокирует доступ.

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

### Базовое назначение

Роль назначается пользователю через админ-панель Cabinet: **Роли → Пользователи роли → Назначить**.

### Временное назначение

Роль может иметь дату истечения (`expires_at`). После этой даты роль автоматически деактивируется — удобно для подрядчиков и временных сотрудников.

### Множественные роли

Пользователь может иметь несколько ролей одновременно. Итоговые разрешения — **объединение** всех разрешений из активных ролей.

## Журнал аудита

Все действия администраторов записываются в неизменяемый журнал аудита:

| Поле     | Описание                                          |
| -------- | ------------------------------------------------- |
| Действие | Что было сделано (create, edit, delete и т.д.)    |
| Ресурс   | Тип и ID объекта (user, tariff, broadcast и т.д.) |
| Статус   | `success` или `denied`                            |
| IP-адрес | Откуда было выполнено действие                    |
| Детали   | Тело запроса и ответа (JSON)                      |
| Время    | Точная метка времени                              |

### Фильтрация

Журнал поддерживает фильтрацию по:

* Пользователю
* Действию
* Типу ресурса
* Статусу (успех / отказ)
* Диапазону дат

### Экспорт

Журнал можно экспортировать в CSV-файл. Требуется разрешение `audit_log:export`.

## Управление через UI

Админ-панель Cabinet содержит полноценный интерфейс для управления RBAC/ABAC:

<Steps>
  <Step title="Роли">
    Раздел **Роли** (`/admin/roles`) — список ролей с цветовыми метками, количеством пользователей. Создание и редактирование ролей с матрицей разрешений.
  </Step>

  <Step title="Назначение">
    Внутри каждой роли — список пользователей и кнопка назначения. Указание срока действия для временного доступа.
  </Step>

  <Step title="Политики">
    Раздел **Политики** (`/admin/policies`) — создание ABAC-правил с конструктором условий (время, IP). Привязка к конкретной роли или глобальная.
  </Step>

  <Step title="Аудит">
    Раздел **Журнал аудита** (`/admin/audit-log`) — просмотр истории всех действий с фильтрами и экспортом.
  </Step>
</Steps>

### Защита интерфейса

Каждый элемент UI защищён проверкой разрешений:

* **Маршруты** — `PermissionRoute` блокирует доступ к страницам без нужного разрешения
* **Элементы** — `PermissionGate` скрывает кнопки и секции, если нет соответствующего разрешения
* **API** — каждый endpoint проверяет разрешение через `require_permission()` и логирует результат

## API-эндпоинты

Базовый путь: `/cabinet/admin/rbac`

### Роли

| Метод  | Путь          | Разрешение     | Описание        |
| ------ | ------------- | -------------- | --------------- |
| GET    | `/roles`      | `roles:read`   | Список ролей    |
| POST   | `/roles`      | `roles:create` | Создание роли   |
| PUT    | `/roles/{id}` | `roles:edit`   | Обновление роли |
| DELETE | `/roles/{id}` | `roles:delete` | Удаление роли   |

### Назначения

| Метод  | Путь                | Разрешение     | Описание          |
| ------ | ------------------- | -------------- | ----------------- |
| POST   | `/assignments`      | `roles:assign` | Назначить роль    |
| DELETE | `/assignments/{id}` | `roles:assign` | Отозвать роль     |
| GET    | `/roles/{id}/users` | `roles:read`   | Пользователи роли |

### Политики

| Метод  | Путь             | Разрешение     | Описание            |
| ------ | ---------------- | -------------- | ------------------- |
| GET    | `/policies`      | `roles:read`   | Список политик      |
| POST   | `/policies`      | `roles:create` | Создание политики   |
| PUT    | `/policies/{id}` | `roles:create` | Обновление политики |
| DELETE | `/policies/{id}` | `roles:create` | Удаление политики   |

### Аудит

| Метод | Путь                | Разрешение         | Описание           |
| ----- | ------------------- | ------------------ | ------------------ |
| GET   | `/audit-log`        | `audit_log:read`   | Журнал с фильтрами |
| GET   | `/audit-log/export` | `audit_log:export` | Экспорт CSV        |

### Реестр

| Метод | Путь           | Разрешение   | Описание                         |
| ----- | -------------- | ------------ | -------------------------------- |
| GET   | `/permissions` | `roles:read` | Список всех доступных разрешений |

## Безопасность

<CardGroup cols={2}>
  <Card title="Иерархия ролей" icon="layer-group">
    Нельзя создавать, редактировать или назначать роли с уровнем ≥ своему. Последний суперадмин защищён от удаления.
  </Card>

  <Card title="Deny побеждает" icon="ban">
    Одна deny-политика ABAC блокирует доступ, даже если RBAC-роль разрешает.
  </Card>

  <Card title="IP-логирование" icon="map-pin">
    IP-адрес извлекается из X-Forwarded-For / X-Real-IP и сохраняется в аудит-логе.
  </Card>

  <Card title="JWT + Telegram" icon="lock">
    Кросс-валидация JWT-токена и X-Telegram-Init-Data предотвращает повторное использование токена.
  </Card>
</CardGroup>
