7.0 KiB
7.0 KiB
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):
[ 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.
- отримують JWT у
2. DATA MODEL (PostgreSQL)
2.1. auth_users
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
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
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
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:
{
"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:
{
"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:
{
"email": "user@example.com",
"password": "StrongPassword123",
"display_name": "Alex"
}
Response (201):
{
"user_id": "uuid",
"email": "user@example.com",
"display_name": "Alex",
"roles": ["user"]
}
4.2. POST /api/auth/login
Request:
{
"email": "user@example.com",
"password": "StrongPassword123"
}
Response (200):
{
"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:
{
"refresh_token": "<JWT_REFRESH>"
}
Response (200):
{
"access_token": "<NEW_JWT_ACCESS>",
"refresh_token": "<NEW_JWT_REFRESH>",
"token_type": "Bearer",
"expires_in": 1800
}
4.4. POST /api/auth/logout
Request:
{
"refresh_token": "<JWT_REFRESH>"
}
Response:
{
"status": "ok"
}
4.5. GET /api/auth/me
Headers: Authorization: Bearer <access_token>
Response (200):
{
"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:
{
"token": "<JWT_ACCESS>"
}
Response (200, valid):
{
"active": true,
"sub": "user_id-uuid",
"email": "user@example.com",
"roles": ["user"],
"exp": 1732591800
}
Response (200, invalid):
{
"active": false
}
6. HEALTHCHECK
GET /healthz
{
"status": "ok",
"service": "auth-service",
"version": "1.0.0"
}
7. CONFIGURATION (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
- Паролі зберігати тільки як
bcrypthash. - 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.