tradein/auth 3: Auth-core — login/logout, session middleware, dual-mode rbac_guard #2552

Open
opened 2026-07-30 06:17:35 +00:00 by lekss361 · 0 comments
Owner

Часть эпика #2549 (шаг 3/8). Блокирован: после #2550 (bcrypt/config) + #2551 (schema). Worker: backend-engineer. deep-code-reviewer обязателен (auth = критичный PR; rbac_guard — центральная точка всех роутов).

Scope

  • app/services/auth_session.py (новый): create/get/revoke session, secrets.token_urlsafe(32), sliding TTL (last_seen_at продлевает), expired-check при lookup.
  • app/api/v1/auth.py (новый): POST /api/v1/auth/login (устанавливает httponly+secure+samesite=lax cookie), POST /api/v1/auth/logout (revoke + clear cookie).
  • app/core/rbac.py: приоритет session-cookie → DB user/role; при AUTH_MODE=dual и отсутствии cookie — fallback на X-Authenticated-User + roles.yaml (легаси pilot→employee маппинг).
  • app/api/v1/me.py: session-first.
  • app/main.py: mount auth.router.
  • Rate-limit на login: ключ username+IP, строже общего; 5 фейлов/окно → 429. События login_success/login_faileduser_events.
  • ⚠️ RateLimitMiddleware/RequestAuditMiddleware ключуются по заголовку x-authenticated-user — резолвленное из сессии имя прокидывать в тот же ключ (иначе session-запросы не лимитируются/не аудируются).

DoD

  • Тесты: login выставляет cookie, /me резолвит роль из DB; dual-mode regression — легаси Caddy-заголовок без cookie работает как раньше (существующие pilot-юзеры не ломаются); 429 на brute-force; logout убирает cookie+запись.
  • Raw-пароль не попадает в логи/Sentry.
  • Требует SESSION_SECRET в прод .env.runtime ДО деплоя — см. #2549 шаг 8 (devops).

Что НЕ делать

Team-CRUD (#шаг 4), фронт (#шаги 5-6), снятие Caddy.

Часть эпика #2549 (шаг 3/8). **Блокирован**: после #2550 (bcrypt/config) + #2551 (schema). Worker: backend-engineer. **deep-code-reviewer обязателен** (auth = критичный PR; rbac_guard — центральная точка всех роутов). ## Scope - `app/services/auth_session.py` (новый): create/get/revoke session, `secrets.token_urlsafe(32)`, sliding TTL (last_seen_at продлевает), expired-check при lookup. - `app/api/v1/auth.py` (новый): `POST /api/v1/auth/login` (устанавливает httponly+secure+samesite=lax cookie), `POST /api/v1/auth/logout` (revoke + clear cookie). - `app/core/rbac.py`: приоритет session-cookie → DB user/role; при `AUTH_MODE=dual` и отсутствии cookie — fallback на `X-Authenticated-User` + roles.yaml (легаси pilot→employee маппинг). - `app/api/v1/me.py`: session-first. - `app/main.py`: mount auth.router. - Rate-limit на login: ключ username+IP, строже общего; 5 фейлов/окно → 429. События `login_success`/`login_failed` → `user_events`. - ⚠️ `RateLimitMiddleware`/`RequestAuditMiddleware` ключуются по заголовку `x-authenticated-user` — резолвленное из сессии имя прокидывать в тот же ключ (иначе session-запросы не лимитируются/не аудируются). ## DoD - Тесты: login выставляет cookie, /me резолвит роль из DB; dual-mode regression — легаси Caddy-заголовок без cookie работает как раньше (существующие pilot-юзеры не ломаются); 429 на brute-force; logout убирает cookie+запись. - Raw-пароль не попадает в логи/Sentry. - Требует `SESSION_SECRET` в прод .env.runtime ДО деплоя — см. #2549 шаг 8 (devops). ## Что НЕ делать Team-CRUD (#шаг 4), фронт (#шаги 5-6), снятие Caddy.
lekss361 added the
auth
scope/backend
security
tradein
labels 2026-07-30 06:23:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2552
No description provided.