Files
microdao-daarion/docs/security/AUTH_SPEC.md

350 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AUTH SPEC — DAARION.city
Version: 1.0.0
---
## 0. PURPOSE
Цей документ описує базову систему автентифікації та авторизації для DAARION.city:
- єдину модель користувача (`user_id`) для:
- фронтенду (web/PWA),
- Matrix/chat інтеграції,
- MicroDAO governance,
- Agents Service,
- SecondMe.
- механізм логіну/логауту (JWT access + refresh tokens),
- базову RBAC (roles/permissions),
- інтеграцію з існуючими сервісами (agents, microdao, city, secondme).
Фокус цієї версії — **MVP-рівень**:
- Password-based login (email + password) + готовність до OAuth (Google/Telegram) як наступний крок.
- JWT токени (access + refresh).
- Мінімальний набір ролей (`user`, `admin`, `agent-system`).
- Захист основних API (governance, agents, secondme private).
---
## 1. ARCHITECTURE OVERVIEW
### 1.1. Auth Service
Окремий сервіс `auth-service` (порт: **7020**):
```text
[ Web / PWA / Matrix Gateway ]
[ Auth Service (7020) ]
[ PostgreSQL (auth tables) + Redis (sessions cache) ]
[ JWT токени для інших сервісів ]
```
Auth Service:
* реєструє користувачів,
* зберігає хеші паролів,
* видає JWT access/refresh токени,
* перевіряє токени (через shared secret / public key),
* надає API для інших сервісів (`/auth/introspect`).
### 1.2. Інші сервіси
* `Agents Service`, `MicroDAO Service`, `SecondMe`, `City Service`:
* отримують JWT у `Authorization: Bearer <token>`,
* валідують його (прямо або через Auth Service),
* витягують `user_id`, `roles`, `scopes`.
---
## 2. DATA MODEL (PostgreSQL)
### 2.1. auth_users
```sql
CREATE TABLE auth_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
display_name TEXT,
avatar_url TEXT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
is_admin BOOLEAN NOT NULL DEFAULT FALSE,
locale TEXT DEFAULT 'uk',
timezone TEXT DEFAULT 'Europe/Kyiv',
meta JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX ix_auth_users_email ON auth_users(email);
```
### 2.2. auth_roles
```sql
CREATE TABLE auth_roles (
id TEXT PRIMARY KEY, -- 'user' | 'admin' | 'agent-system'
description TEXT
);
INSERT INTO auth_roles (id, description) VALUES
('user', 'Regular user'),
('admin', 'Administrator'),
('agent-system', 'System agent');
```
### 2.3. auth_user_roles
```sql
CREATE TABLE auth_user_roles (
user_id UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
role_id TEXT NOT NULL REFERENCES auth_roles(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, role_id)
);
```
### 2.4. auth_sessions
```sql
CREATE TABLE auth_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
user_agent TEXT,
ip_address INET,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expires_at TIMESTAMPTZ NOT NULL,
revoked_at TIMESTAMPTZ,
meta JSONB DEFAULT '{}'::jsonb
);
CREATE INDEX ix_auth_sessions_user_id ON auth_sessions(user_id);
CREATE INDEX ix_auth_sessions_expires ON auth_sessions(expires_at);
```
---
## 3. TOKEN MODEL (JWT)
### 3.1. Access token
* Формат: JWT (HS256).
* Термін дії: 30 хвилин.
* Payload:
```json
{
"sub": "user_id-uuid",
"email": "user@example.com",
"name": "Display Name",
"roles": ["user"],
"iat": 1732590000,
"exp": 1732591800,
"iss": "daarion-auth",
"type": "access"
}
```
### 3.2. Refresh token
* Формат: JWT (HS256).
* Термін дії: 7 днів.
* Payload:
```json
{
"sub": "user_id-uuid",
"session_id": "session-uuid",
"iat": 1732590000,
"exp": 1733194800,
"iss": "daarion-auth",
"type": "refresh"
}
```
---
## 4. HTTP API (PUBLIC)
Базовий шлях: `/api/auth/...`.
### 4.1. `POST /api/auth/register`
**Request:**
```json
{
"email": "user@example.com",
"password": "StrongPassword123",
"display_name": "Alex"
}
```
**Response (201):**
```json
{
"user_id": "uuid",
"email": "user@example.com",
"display_name": "Alex",
"roles": ["user"]
}
```
### 4.2. `POST /api/auth/login`
**Request:**
```json
{
"email": "user@example.com",
"password": "StrongPassword123"
}
```
**Response (200):**
```json
{
"access_token": "<JWT_ACCESS>",
"refresh_token": "<JWT_REFRESH>",
"token_type": "Bearer",
"expires_in": 1800,
"user": {
"id": "uuid",
"email": "user@example.com",
"display_name": "Alex",
"roles": ["user"]
}
}
```
### 4.3. `POST /api/auth/refresh`
**Request:**
```json
{
"refresh_token": "<JWT_REFRESH>"
}
```
**Response (200):**
```json
{
"access_token": "<NEW_JWT_ACCESS>",
"refresh_token": "<NEW_JWT_REFRESH>",
"token_type": "Bearer",
"expires_in": 1800
}
```
### 4.4. `POST /api/auth/logout`
**Request:**
```json
{
"refresh_token": "<JWT_REFRESH>"
}
```
**Response:**
```json
{
"status": "ok"
}
```
### 4.5. `GET /api/auth/me`
**Headers:** `Authorization: Bearer <access_token>`
**Response (200):**
```json
{
"id": "uuid",
"email": "user@example.com",
"display_name": "Alex",
"avatar_url": null,
"roles": ["user"],
"created_at": "2025-11-26T10:00:00Z"
}
```
---
## 5. HTTP API (INTERNAL)
### 5.1. `POST /api/auth/introspect`
**Request:**
```json
{
"token": "<JWT_ACCESS>"
}
```
**Response (200, valid):**
```json
{
"active": true,
"sub": "user_id-uuid",
"email": "user@example.com",
"roles": ["user"],
"exp": 1732591800
}
```
**Response (200, invalid):**
```json
{
"active": false
}
```
---
## 6. HEALTHCHECK
### `GET /healthz`
```json
{
"status": "ok",
"service": "auth-service",
"version": "1.0.0"
}
```
---
## 7. CONFIGURATION (ENV)
```env
AUTH_SERVICE_PORT=7020
AUTH_DB_DSN=postgresql://user:pass@postgres:5432/daarion
AUTH_JWT_SECRET=your-very-long-secret-key-here
AUTH_ACCESS_TOKEN_TTL=1800
AUTH_REFRESH_TOKEN_TTL=604800
AUTH_BCRYPT_ROUNDS=12
```
---
## 8. SECURITY NOTES
* Паролі зберігати тільки як `bcrypt` hash.
* JWT secret — довгий (мінімум 32 символи), збережений у `.env`.
* Rate limiting для `/auth/login` (захист від brute force).
* Логи не повинні писати паролі / токени.
* HTTPS обов'язковий у production.
---
## 9. ROADMAP (POST-MVP)
* OAuth2 / OIDC (Google, GitHub, Telegram).
* WebAuthn / passkeys.
* Device-level identity (звʼязок із Matrix devices).
* On-chain identity (wallet + DID).
* Email verification.
* Password reset flow.