mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
A release-readiness QA pass over the whole product. The commits split into defects a user would hit and gates that were reporting green while measuring nothing. ## Fixes that change behaviour Rate limiting was bypassable on every install: TRUST_PROXY defaulted to true, so request.ip came from a client-set header and a forged X-Forwarded-For got past the login limiter. The default is now a private-network trust list. A transient Postgres outage stranded in-flight jobs, leaving finished output on disk with no row pointing at it. A reconciler now resolves those rows and adopts the bytes rather than dropping the work. A Redis connection that moved to a new address wedged every read-blocked consumer, so completions stopped signalling while health still answered 200. Socket timeouts plus subscriber pings recover it. Installing more than one AI bundle left the shared venv multi-versioned and silently broke three tools. The installer now reconciles distributions to one version each. Converting an image to JXL at quality 1 through 4 returned a 500, because libjxl 0.7 rejects the distance those values compute. The quality is floored at what the encoder honours. A missing ffmpeg was also reported to the user as a corrupt upload; it now says the engine is unavailable. RAW uploads reached an unpatched LibRaw on arm64, so it is built from source at 0.22.2, and the release scan was split so it can fail on an unfixed critical instead of hiding it behind ignore-unfixed. ## Gates that could not fail Two mutation lanes ran zero mutants because Stryker crawled the gitignored docs build; coverage discarded its whole report on any failing test; the lint gate skipped root tests, scripts, and two workspaces; and several generated matrices counted a host missing ffmpeg as a passing tool. Each now measures what it claims. Full evidence and the outstanding release items are tracked locally and are not part of this branch.
268 lines
19 KiB
Markdown
268 lines
19 KiB
Markdown
---
|
||
description: "Керуйте користувачами, вбудованими та власними ролями, дозволами, ключами API, командами, сеансами й журналом аудиту в SnapOtter."
|
||
i18n_source_hash: bea8955f3aff
|
||
i18n_provenance: human
|
||
i18n_output_hash: 802ed8983042
|
||
i18n_hash_version: 2
|
||
---
|
||
|
||
# Користувачі, ролі та дозволи {#users-roles-permissions}
|
||
|
||
SnapOtter постачається з трьома вбудованими ролями, 17 деталізованими дозволами та підтримкою власних ролей із необов'язковим контролем доступу на рівні окремих інструментів. Ця сторінка охоплює повну модель авторизації, обмеження області дії ключів API, керування командами та журналювання аудиту.
|
||
|
||
::: tip Пов'язані сторінки
|
||
[OIDC / SSO](/uk/guide/oidc) | [SAML SSO](/uk/guide/saml) | [Провізіювання SCIM](/uk/guide/scim) | [Безпека та посилення захисту](/uk/guide/security)
|
||
:::
|
||
|
||
## Користувачі {#users}
|
||
|
||
### Створення користувачів {#creating-users}
|
||
|
||
Адміністратори можуть створювати користувачів через панель адміністратора або кінцеву точку `POST /api/auth/register`. Кожен користувач має ім'я користувача, роль, призначення до команди та необов'язкову адресу електронної пошти.
|
||
|
||
### Типовий адміністратор {#default-admin}
|
||
|
||
Під час першого запуску SnapOtter створює типовий обліковий запис адміністратора. Облікові дані беруться зі змінних середовища:
|
||
|
||
| Змінна | Типове значення | Опис |
|
||
|---|---|---|
|
||
| `DEFAULT_USERNAME` | `admin` | Ім'я користувача для початкового облікового запису адміністратора |
|
||
| `DEFAULT_PASSWORD` | `admin` | Пароль для початкового облікового запису адміністратора |
|
||
|
||
Типовий адміністратор зобов'язаний змінити свій пароль під час першого входу.
|
||
|
||
### Провайдери автентифікації {#authentication-providers}
|
||
|
||
Користувачі можуть автентифікуватися кількома способами:
|
||
|
||
- **Локально** - ім'я користувача та пароль, що зберігаються в базі даних SnapOtter
|
||
- **OIDC** - будь-який провайдер OpenID Connect (див. [OIDC / SSO](/uk/guide/oidc))
|
||
- **SAML** - постачальники ідентичності SAML 2.0 (див. [SAML SSO](/uk/guide/saml))
|
||
- **SCIM** - автоматизоване провізіювання від постачальника ідентичності (див. [Провізіювання SCIM](/uk/guide/scim))
|
||
|
||
### Вимкнення автентифікації {#disabling-authentication}
|
||
|
||
Задайте `AUTH_ENABLED=false`, щоб повністю вимкнути автентифікацію. У цьому режимі для всіх запитів використовується синтетичний анонімний користувач із роллю `admin`. Вхід не потрібен.
|
||
|
||
::: warning
|
||
Вимкнення автентифікації надає повний доступ адміністратора будь-кому, хто може дістатися екземпляра. Використовуйте це лише в довірених середовищах.
|
||
:::
|
||
|
||
## Вбудовані ролі {#built-in-roles}
|
||
|
||
SnapOtter містить три вбудовані ролі. Їх не можна змінити чи видалити.
|
||
|
||
### Admin {#admin}
|
||
|
||
Усі 17 дозволів. Повний контроль над екземпляром.
|
||
|
||
`tools:use` `files:own` `files:all` `apikeys:own` `apikeys:all` `pipelines:own` `pipelines:all` `settings:read` `settings:write` `users:manage` `teams:manage` `features:manage` `system:health` `audit:read` `compliance:manage` `webhooks:manage` `security:manage`
|
||
|
||
### Editor {#editor}
|
||
|
||
7 дозволів. Може використовувати всі інструменти та керувати всіма файлами й конвеєрами, але не має доступу до адміністративних функцій.
|
||
|
||
`tools:use` `files:own` `files:all` `apikeys:own` `pipelines:own` `pipelines:all` `settings:read`
|
||
|
||
### User {#user}
|
||
|
||
5 дозволів. Може використовувати інструменти та керувати власними ресурсами.
|
||
|
||
`tools:use` `files:own` `apikeys:own` `pipelines:own` `settings:read`
|
||
|
||
## Довідник дозволів {#permissions-reference}
|
||
|
||
| Дозвіл | Опис |
|
||
|---|---|
|
||
| `tools:use` | Використовувати будь-який інструмент обробки |
|
||
| `files:own` | Переглядати власні файли та керувати ними |
|
||
| `files:all` | Переглядати файли всіх користувачів та керувати ними |
|
||
| `apikeys:own` | Створювати власні ключі API та керувати ними |
|
||
| `apikeys:all` | Переглядати ключі API всіх користувачів |
|
||
| `pipelines:own` | Створювати власні конвеєри та керувати ними |
|
||
| `pipelines:all` | Переглядати конвеєри всіх користувачів та керувати ними |
|
||
| `settings:read` | Переглядати налаштування екземпляра |
|
||
| `settings:write` | Змінювати налаштування екземпляра |
|
||
| `users:manage` | Створюйте облікові записи користувачів і керуйте ними в межах повноважень актора |
|
||
| `teams:manage` | Створювати, оновлювати та видаляти команди |
|
||
| `features:manage` | Встановлювати комплекти AI-функцій та керувати ними |
|
||
| `system:health` | Доступ до кінцевих точок стану та готовності |
|
||
| `audit:read` | Переглядати журнал аудиту та перелічувати ролі |
|
||
| `compliance:manage` | Керуйте життєвим циклом GDPR і функціями відповідності; деструктивні операції користувача залишаються обмеженими повноваженнями |
|
||
| `webhooks:manage` | Налаштовувати вихідні вебхуки |
|
||
| `security:manage` | Керувати налаштуваннями безпеки (список дозволених IP, примусове застосування SSO) |
|
||
|
||
## Власні ролі {#custom-roles}
|
||
|
||
Адміністратори з дозволом `security:manage` можуть створювати власні ролі через панель адміністратора або API ролей. Перелічення ролей потребує `audit:read`.
|
||
|
||
### Створення власної ролі {#creating-a-custom-role}
|
||
|
||
```bash
|
||
curl -X POST http://localhost:1349/api/v1/roles \
|
||
-H "Authorization: Bearer si_..." \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "reviewer",
|
||
"description": "Can use tools and view all files",
|
||
"permissions": ["tools:use", "files:own", "files:all", "settings:read"]
|
||
}'
|
||
```
|
||
|
||
Назви ролей мають бути 2-30 символів, малими літерами, буквено-цифровими, з дефісами й підкресленнями.
|
||
|
||
### Межі делегованого адміністрування {#delegated-administration-boundaries}
|
||
|
||
Усі 17 дозволів можна делегувати за допомогою спеціальних ролей, але адміністративний дозвіл не робить цю роль еквівалентною вбудованій ролі `admin`. Мутації користувача, дозволені `users:manage`, деструктивні операції, дозволені `compliance:manage`, і керування нестандартними ролями, дозволені `security:manage`, обмежені поточними повноваженнями актора:
|
||
|
||
- Вбудовані ролі слідують за `admin` > `editor` > `user`; настроювані ролі знаходяться нижче вбудованих ролей.
|
||
- Дозволи цілі повинні міститися в **ефективних** дозволах актора. Таким чином, ключ API із обмеженою областю не може використовувати дозволи, випущені з його області.
|
||
- Доступ до інструментів цільової ролі має бути обмежений власним доступом до інструментів актора.
|
||
- Вимкнений обліковий запис перевіряється на його початкову роль, якщо ця роль записана як `disabled:<original-role>`.
|
||
- Для видалення настроюваної ролі також потрібні повноваження для призначення вбудованого резервного варіанта `user`; недієздатні учасники залишаються недієздатними як `disabled:user`.
|
||
|
||
Глобальні облікові дані та конфігурація суворіші: для видачі або відкликання маркера SCIM та імпорту конфігурації екземпляра потрібна вбудована роль `admin` із повними ефективними повноваженнями адміністратора.
|
||
|
||
### Дозволи на рівні інструментів {#tool-level-permissions}
|
||
|
||
Власні ролі можуть за бажанням обмежувати, до яких інструментів мають доступ користувачі. Доступні два режими:
|
||
|
||
| Режим | Поведінка | Вимога до ліцензії |
|
||
|---|---|---|
|
||
| `category` | Обмеження за модальністю (image, video, audio, document, file) | Немає (безкоштовно) |
|
||
| `tool` | Обмеження за ID окремого інструмента | Потребує корпоративної функції `per_tool_permissions` |
|
||
|
||
Коли задано режим `tool`, але корпоративна функція недоступна, SnapOtter коректно деградує та дозволяє доступ до всіх інструментів.
|
||
|
||
```json
|
||
{
|
||
"name": "image-only",
|
||
"permissions": ["tools:use", "files:own"],
|
||
"toolPermissions": {
|
||
"mode": "category",
|
||
"allowed": ["image"]
|
||
}
|
||
}
|
||
```
|
||
|
||
### Видалення власної ролі {#deleting-a-custom-role}
|
||
|
||
Коли власну роль видаляють, усіх призначених до неї користувачів автоматично переназначають на роль `user`.
|
||
|
||
## Команди {#teams}
|
||
|
||
Команди групують користувачів для керування сховищем і збереженням. Команда `Default` створюється під час першого запуску.
|
||
|
||
| Поле | Тип | Опис |
|
||
|---|---|---|
|
||
| `name` | string | Унікальна назва команди (1-50 символів) |
|
||
| `storageQuota` | number | Обмеження сховища для команди в байтах (працює без корпоративної ліцензії) |
|
||
| `retentionHours` | number | Автовидалення результатів після стількох годин (потребує `team_retention_overrides`, корпоративна) |
|
||
| `legalHold` | boolean | Запобігати автоматичному видаленню файлів учасників команди (потребує `legal_hold`, корпоративна) |
|
||
|
||
::: info
|
||
Команду `Default` не можна видалити. Команди, у яких досі є учасники, видалити не можна. Спершу переназначте учасників.
|
||
:::
|
||
|
||
## Ключі API {#api-keys}
|
||
|
||
Користувачі можуть генерувати ключі API для програмного доступу. Кожен ключ використовує префікс `si_` і показується лише один раз під час створення.
|
||
|
||
### Дозволи з обмеженою областю дії {#scoped-permissions}
|
||
|
||
Ключі API можуть за бажанням нести масив `permissions`. Коли його задано, ефективні дозволи для запиту - це **перетин** дозволів ролі користувача та дозволів з обмеженою областю дії ключа. Це означає, що ключ API ніколи не може вийти за межі власних дозволів користувача.
|
||
|
||
```bash
|
||
curl -X POST http://localhost:1349/api/v1/api-keys \
|
||
-H "Authorization: Bearer si_..." \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "CI pipeline key",
|
||
"permissions": ["tools:use", "files:own"],
|
||
"expiresAt": "2027-01-01T00:00:00Z"
|
||
}'
|
||
```
|
||
|
||
### Термін дії {#expiration}
|
||
|
||
Ключі приймають необов'язкову позначку часу `expiresAt`. Ключі з простроченим терміном дії відхиляються під час автентифікації.
|
||
|
||
## Журнал аудиту {#audit-log}
|
||
|
||
SnapOtter записує події, важливі для безпеки, у структурований журнал аудиту, що зберігається в таблиці бази даних `audit_log`.
|
||
|
||
### Перегляд журналу аудиту {#viewing-the-audit-log}
|
||
|
||
```
|
||
GET /api/v1/audit-log?page=1&limit=50&action=LOGIN_FAILED&from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z
|
||
```
|
||
|
||
Потребує дозволу `audit:read`. Підтримує пагінацію (`page`, `limit`) та фільтри (`action`, `ip`, `from`, `to`).
|
||
|
||
### Аудит операцій з інструментами {#tool-operation-auditing}
|
||
|
||
::: warning
|
||
Події `TOOL_EXECUTED` **не** журналюються за замовчуванням. Вони вмикаються за вибором через один із двох шляхів:
|
||
|
||
1. Задайте адміністративне налаштування `auditToolOperations` у `true`.
|
||
2. Майте активну ліцензію з функцією `audit_export` (доступна як у планах team, так і enterprise).
|
||
|
||
Без одного з цих варіантів окремі виконання інструментів не записуються в журнал аудиту.
|
||
:::
|
||
|
||
### Експорт {#exporting}
|
||
|
||
```
|
||
GET /api/v1/enterprise/audit/export?format=csv&from=2026-01-01T00:00:00Z
|
||
```
|
||
|
||
Потребує дозволу `audit:read` та корпоративної функції `audit_export` (доступна як у планах team, так і enterprise). Підтримує формати CSV та JSON, фільтровані за `action`, `actorId`, `targetType`, `targetId`, `from` та `to`.
|
||
|
||
### Підписування, стійке до підробки {#tamper-resistant-signing}
|
||
|
||
Коли ввімкнено, кожен запис журналу аудиту підписується за допомогою HMAC, похідного від `DATA_ENCRYPTION_KEY`. Це потребує:
|
||
|
||
1. Задання `DATA_ENCRYPTION_KEY` у вашому середовищі.
|
||
2. Увімкнення адміністративного налаштування `tamperResistantAudit`.
|
||
3. Корпоративної ліцензії з функцією `tamper_resistant_audit`.
|
||
|
||
### Збереження {#retention}
|
||
|
||
Задайте `AUDIT_RETENTION_DAYS`, щоб автоматично очищати старі записи. Типове значення - `0`, що означає, що записи зберігаються безстроково.
|
||
|
||
### Довідник подій {#event-reference}
|
||
|
||
| Подія | Категорія |
|
||
|---|---|
|
||
| `LOGIN_SUCCESS`, `LOGIN_FAILED` | Автентифікація |
|
||
| `OIDC_LOGIN_SUCCESS`, `OIDC_LOGIN_FAILED` | Автентифікація |
|
||
| `SAML_LOGIN_SUCCESS`, `SAML_LOGIN_FAILED` | Автентифікація |
|
||
| `LOGOUT` | Автентифікація |
|
||
| `USER_CREATED`, `USER_UPDATED`, `USER_DELETED` | Керування користувачами |
|
||
| `PASSWORD_CHANGED`, `PASSWORD_RESET` | Керування користувачами |
|
||
| `MFA_ENROLLED`, `MFA_DISABLED`, `MFA_VERIFIED`, `MFA_VERIFY_FAILED` | MFA |
|
||
| `MFA_CHALLENGE_ISSUED`, `MFA_RECOVERY_USED`, `MFA_RESET` | MFA |
|
||
| `ROLE_CREATED`, `ROLE_UPDATED`, `ROLE_DELETED` | Ролі |
|
||
| `API_KEY_CREATED`, `API_KEY_DELETED` | Ключі API |
|
||
| `SETTINGS_UPDATED`, `IP_ALLOWLIST_UPDATED` | Налаштування |
|
||
| `FILE_UPLOADED`, `FILE_DELETED` | Файли |
|
||
| `TOOL_EXECUTED` | Інструменти (за вибором) |
|
||
| `SCIM_USER_PROVISIONED`, `SCIM_USER_UPDATED`, `SCIM_USER_DEPROVISIONED` | SCIM |
|
||
| `SCIM_GROUP_SYNCED` | SCIM |
|
||
| `LEGAL_HOLD_APPLIED`, `LEGAL_HOLD_RELEASED` | Відповідність |
|
||
| `GDPR_EXPORT_INITIATED`, `GDPR_USER_PURGED`, `GDPR_TEAM_PURGED` | Відповідність |
|
||
| `CONFIG_EXPORTED`, `CONFIG_IMPORTED` | Конфігурація |
|
||
|
||
## Керування сеансами {#session-management}
|
||
|
||
Сеанси базуються на кукі та керуються `SESSION_DURATION_HOURS` (типово: 168 годин / 7 днів).
|
||
|
||
### Зміна ролі анулює сеанси {#role-changes-invalidate-sessions}
|
||
|
||
Коли адміністратор змінює роль користувача, усі активні сеанси цього користувача видаляються. Користувач має увійти знову, щоб отримати свої нові дозволи.
|
||
|
||
### Запобіжники безпеки {#safety-guards}
|
||
|
||
- **Захист останнього адміністратора**: останнього адміністратора не можна понизити до нижчої ролі. API повертає помилку, якщо ви спробуєте.
|
||
- **Запобігання самовидаленню**: адміністратори не можуть видалити власний обліковий запис через API.
|