Some checks failed
Test Suite / lint-backend (push) Waiting to run
Test Suite / build-frontend (push) Waiting to run
Test Suite / k6 /health Baseline (push) Waiting to run
Test Suite / playwright-tests (push) Waiting to run
Deploy Development / deploy (push) Failing after 0s
Test Suite / pytest-backend (push) Has been cancelled
Co-authored-by: Cursor <cursoragent@cursor.com>
3.9 KiB
3.9 KiB
Auth & Session – Designprinzipien (Extraktion)
Status: Analyse / Arbeitspapier
Stand: 2026-07-04
Geltungsbereich: Modul „Auth & Session“ — gemeinsame Mitai-Basis in Shinkan
Serie: Designprinzipien für Produktfamilie · Shinkan Dokument 4 von 15
Mitai-Vergleich: AUTH_SESSION_DESIGN_PRINCIPLES.md (#5)
Kernkomponenten:
| Bereich | Pfade |
|---|---|
| Auth-Kern | backend/auth.py |
| Router | backend/routers/auth.py, profiles.py |
| Frontend | frontend/src/context/AuthContext.jsx, frontend/src/api/client.js |
| Account-Lifecycle | backend/account_lifecycle.py |
Modul
Auth & Session
Token-basierte Server-Sessions (sessions-Tabelle), bcrypt-Passwörter, FastAPI-Dependencies require_auth / require_admin. Geteilter Code mit Mitai (App-Familie).
Fachliche Verantwortung
- Login/Logout/Session-Lebensdauer
- Passwort-Hashing (bcrypt, Legacy-SHA256-Upgrade)
- Auth-Dependencies für Router
- Account-States (Verifizierung, Onboarding-Gates)
Designprinzipien
1. Server-Side Sessions mit Token
| Prinzip | X-Auth-Token Header → Lookup in sessions mit Ablaufzeit. |
| Begründung | Widerrufbar; kein JWT-Drift zwischen Apps. |
| Quelle | auth.py get_session, require_auth |
| Tragfähigkeit | hoch (Familien-Standard) |
| Einschränkung | Kein Refresh-Token-Rotation-Modell. |
2. require_auth als separater Depends-Parameter
| Prinzip | session: dict = Depends(require_auth) — nie in Header-Default eingebettet. |
| Begründung | Bekannter FastAPI-Footgun führt zu ungeschützten Endpoints. |
| Quelle | CLAUDE.md Kritische Regeln |
| Tragfähigkeit | hoch |
| Einschränkung | Code-Review/Lint erzwingt das nicht automatisch. |
3. Profile-ID immer aus Session
| Prinzip | profile_id aus session['profile_id'], nie aus Client-Header als Autorität. |
| Begründung | IDOR-Vermeidung. |
| Quelle | Architektur-Regeln; Shinkan ergänzt TenantContext.profile_id |
| Tragfähigkeit | hoch |
| Einschränkung | Mitai-Dokument nennt Profile-Header-Schwäche — in Shinkan prüfen ob analog. |
4. bcrypt für alle Passwort-Operationen
| Prinzip | hash_pin / verify_pin mit bcrypt; SHA256 nur Legacy-Verify + Upgrade. |
| Begründung | Familien-konsistente Kryptografie. |
| Quelle | auth.py |
| Tragfähigkeit | hoch |
| Einschränkung | — |
5. Portal-Rollen vs. Vereinsrollen trennen
| Prinzip | profiles.role (admin/superadmin/user) ≠ club_member_roles im Verein. |
| Begründung | Shinkan-Mandantenmodell; Plattform-Admin ≠ Vereins-Trainer. |
| Quelle | club_tenancy.py; TenantContext.global_role |
| Tragfähigkeit | hoch |
| Einschränkung | UI muss beide Ebenen korrekt anzeigen. |
6. Account-Lifecycle als Capability-Voraussetzung
| Prinzip | min_account_state auf Capabilities (z. B. verifiziertes Mitglied). |
| Begründung | Gates vor sensiblen Aktionen ohne Sonderchecks in Routern. |
| Quelle | account_lifecycle.py; capabilities.py |
| Tragfähigkeit | mittel |
| Einschränkung | Nicht alle Flows nutzen Lifecycle einheitlich. |
Nicht übernehmen
- Auth-Parameter in Header-Defaults vermischen — dokumentierter Anti-Pattern.
- Client-gesteuerte
profile_idfür Autorisierung. - Shinkan-spezifische Mandantenlogik in
auth.py— gehört intenant_context.py.