Автентифікація
DocPlatform підтримує локальну автентифікацію (email + пароль) одразу після встановлення, з опціональним входом через Google та GitHub OIDC для команд, що використовують цих провайдерів.
Локальна автентифікація (за замовчуванням)
Локальна автентифікація працює без жодної конфігурації. Користувачі реєструються з email та паролем, і входять з тими ж обліковими даними.
Як це працює
- Реєстрація — Користувач надсилає email + пароль. Пароль хешується за допомогою argon2id (рекомендований алгоритм OWASP 2024).
- Вхід — Користувач надсилає облікові дані. Сервер перевіряє хеш пароля та повертає JWT токени.
- Сесія — Токен доступу (RS256, 15-хвилинний час життя) надсилається з кожним API запитом. Токен оновлення (30-денний час життя) використовується для отримання нових токенів доступу без повторної автентифікації.
Хешування паролів
DocPlatform використовує argon2id з наступними параметрами (стандарт OWASP 2024):
| Параметр | Значення |
|---|---|
| Алгоритм | argon2id |
| Пам’ять | 64 МБ |
| Ітерації | 3 |
| Паралелізм | 4 |
| Довжина солі | 16 байт |
| Довжина ключа | 32 байти |
Ці параметри не налаштовуються — вони відповідають найкращим практикам безпеки. Хеші паролів зберігаються в базі даних SQLite та ніколи не залишають сервер.
Скидання пароля
Коли користувач запитує скидання пароля:
- З налаштованим SMTP — одноразове посилання для скидання надсилається на email користувача
- Без SMTP — токен скидання виводиться в stdout (логи сервера)
# Check server logs for the reset token
docplatform serve 2>&1 | grep "password reset"
Токен дійсний протягом 1 години та може бути використаний лише один раз.
JWT токени
DocPlatform видає RS256 (RSA-SHA256) JSON Web Tokens для автентифікації.
Життєвий цикл токенів
User logs in
│
▼
┌─────────────────────────────────┐
│ Access Token (15 min) │ ──► Sent with every API request
│ Refresh Token (30 days) │ ──► Used to get new access tokens
└─────────────────────────────────┘
│
│ Access token expires
▼
┌─────────────────────────────────┐
│ POST /api/v1/auth/refresh │
│ Body: { refresh_token: "..." } │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ New Access Token (15 min) │ ──► Old refresh token rotated
│ New Refresh Token (30 days) │ ──► Old one invalidated
└─────────────────────────────────┘
Ротація токенів оновлення
Кожного разу, коли використовується токен оновлення, видається новий токен оновлення, а старий інвалідується. Це обмежує вікно вразливості у разі компрометації токена.
Конфігурація
| Змінна | За замовчуванням | Опис |
|---|---|---|
JWT_SECRET_PATH |
{DATA_DIR}/jwt-key.pem |
Шлях до приватного ключа RS256 |
JWT_ACCESS_TTL |
900 |
Час життя токена доступу (секунди) |
JWT_REFRESH_TTL |
2592000 |
Час життя токена оновлення (секунди) |
Управління ключами
Пара ключів RS256 автоматично генерується при першому запуску, якщо файл не існує. Для ротації ключів:
- Зупиніть сервер
- Видаліть файл ключа (
{DATA_DIR}/jwt-key.pem) - Запустіть сервер — новий ключ буде згенеровано
Усі наявні сесії інвалідуються при ротації ключів. Користувачі повинні увійти знову.
Вхід через Google OIDC (опціонально)
Дозвольте користувачам входити за допомогою облікового запису Google.
Налаштування
- Перейдіть до Google Cloud Console
- Створіть новий проєкт (або використовуйте наявний)
- Перейдіть до APIs & Services → Credentials
- Натисніть Create Credentials → OAuth 2.0 Client ID
- Тип додатка: Web application
- Додайте авторизований redirect URI:
https://your-domain.com/api/v1/auth/callback/google - Скопіюйте Client ID та Client Secret
Встановіть змінні середовища:
export OIDC_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
export OIDC_GOOGLE_CLIENT_SECRET=your-client-secret
Перезапустіть сервер. На сторінці входу з’явиться кнопка Sign in with Google.
Створення облікового запису
Коли користувач вперше входить через Google:
- Створюється обліковий запис DocPlatform з його Google email
- Йому призначається роль за замовчуванням (
permissions.default_role) у будь-якому робочому просторі, до якого його запрошують - Пароль не встановлюється (його можна додати пізніше через профіль)
Вхід через GitHub OIDC (опціонально)
Дозвольте користувачам входити за допомогою облікового запису GitHub.
Налаштування
- Перейдіть до GitHub Developer Settings
- Натисніть New OAuth App
- Встановіть authorization callback URL:
https://your-domain.com/api/v1/auth/callback/github - Скопіюйте Client ID та згенеруйте Client Secret
Встановіть змінні середовища:
export OIDC_GITHUB_CLIENT_ID=your-client-id
export OIDC_GITHUB_CLIENT_SECRET=your-client-secret
Перезапустіть сервер. На сторінці входу з’явиться кнопка Sign in with GitHub.
Створення облікового запису
Так само як і для Google — створюється обліковий запис DocPlatform із використанням основного email GitHub. Якщо обліковий запис GitHub не має публічного email, користувачу буде запропоновано ввести його.
Управління сесіями
DocPlatform відстежує активні сесії для кожного користувача:
| Поле | Опис |
|---|---|
| Пристрій | Рядок user-agent |
| IP-адреса | IP клієнта (для цілей аудиту) |
| Створено | Коли сесію було встановлено |
| Остання активність | Останній API запит |
Користувачі можуть переглядати та відкликати сесії зі своєї сторінки профілю. Адміністратори можуть переглядати всі сесії з панелі адміністрування.
Відкликання сесій
- Ініційоване користувачем — Profile → Sessions → Revoke
- Ініційоване адміністратором — Admin → Users → обрати користувача → Revoke All Sessions
- Ротація ключів — видалення JWT ключа інвалідує всі сесії глобально
Політика паролів
| Обмеження | Значення |
|---|---|
| Мінімальна довжина | 8 символів |
| Максимальна довжина | 128 символів |
| Хешування | argon2id (64 МБ пам’яті, 3 ітерації, паралелізм 4) |
Паролі перевіряються при реєстрації та скиданні пароля. DocPlatform не вимагає вимог до класів символів (великі літери, спеціальні символи) — довжина є основним заходом безпеки відповідно до поточних рекомендацій NIST.
Автентифікація WebSocket
WebSocket з’єднання використовують шаблон одноразового ticket, щоб уникнути розкриття JWT токенів у URL (які б з’явилися в логах сервера та історії браузера).
Послідовність:
- Клієнт викликає
POST /api/v1/auth/ws-ticketз валідним JWT - Сервер повертає випадковий ticket (дійсний 30 секунд, одноразовий)
- Клієнт підключається до
ws://host/ws?ticket={ticket} - Сервер перевіряє ticket, встановлює WebSocket та видаляє ticket
Це прозоро для користувачів — веб-редактор автоматично отримує ticket.
Рекомендації щодо безпеки
- Увімкніть OIDC для команд із обліковими записами Google або GitHub — делегує управління паролями надійним провайдерам
- Використовуйте HTTPS у виробництві — JWT токени є bearer-токенами; перехоплені токени дають повний доступ
- Тримайте час життя токенів коротким — 15-хвилинні токени доступу обмежують вразливість
- Контролюйте сесії — регулярно переглядайте активні сесії на предмет неочікуваних пристроїв або IP
- Здійснюйте ротацію ключів щорічно або після будь-якої підозри на компрометацію
- Використовуйте HttpOnly cookies — DocPlatform зберігає токени в HttpOnly + Secure + SameSite=Strict cookies, запобігаючи крадіжці токенів через XSS