SEC-1b-6 MFA Plan-Review — Mehrfaktor-Authentifizierung vor MH-5b/c/d

Projekt: Steve-TradingBot · Phase: SEC-1b-6 (MFA) · Author: claude-opus-4-7[1m]
Generated: 2026-05-13 07:34 UTC · master HEAD: a185182 (MH-5a closed)
Status: NO CODE Plan-Review only — Operator-GO erforderlich vor SEC-1b-6 Code-Phase
Empfehlung: Variante D — Staged (TOTP jetzt, Passkey BACKLOG)

Ziel: MFA-Pflicht für Admin-Logins, damit MH-5b/c/d Mutation-Actions (Approve / Reject / Pause / Resume / Release) sicher freigeschaltet werden können.

Vorbedingung: SEC-1b-0/1/2/3/4/5 abgeschlossen, MH-5a (Read-only ManagedProposalResource) live.


1 — Live-State-Check (Boundaries)

ItemValue
master HEADa185182
git statusclean (außer Container-Rename-Reste, DEFERRED)
GUI HTTP /admin/login(Reverse-Proxy-Übergang gerade aktiv — ungefährlich)
APP_URLhttp://127.0.0.1:8090PLAIN HTTP
SESSION_SECURE_COOKIEnicht gesetzt
Bot in-container PIDunverändert
Worker in-container PIDunverändert
BINANCE_TESTNETtrue
Mainnet5-layer block
managed_proposals rows0
Installierte MFA-Bausteinepragmarx/google2fa 9.0.0 + pragmarx/google2fa-qrcode 3.0.0
Filament-native MFAvendor/filament/filament/src/Auth/MultiFactor/{App,Email,Contracts,Http,Pages}

Major Finding: Filament 5 hat native TOTP-MFA + native Email-MFA out-of-the-box. Pakete pragmarx/google2fa{,-qrcode} sind bereits installiert (transitive aus filament/filament). Kein zusätzliches Composer-Paket nötig für Option A.

Blocker-Finding: APP_URL=http://… → die GUI läuft aktuell ohne HTTPS. WebAuthn/Passkey funktioniert nur in einem „secure context“ (HTTPS mit gültigem Zertifikat) — siehe SEC-1a H5 (self-signed cert). Browser akzeptieren Passkey-Enrollment praktisch nicht über plain HTTP und nur unzuverlässig über self-signed HTTPS.


2 — Option A: TOTP / Authenticator-App (Filament-native)

Mechanik

  1. User-Tabelle erhält 2 verschlüsselte Spalten:
  2. User implementiert HasAppAuthentication + HasAppAuthenticationRecovery:
    public function getAppAuthenticationSecret(): ?string;
    public function saveAppAuthenticationSecret(?string $secret): void;
    public function getAppAuthenticationHolderName(): string;        // → email
    public function getAppAuthenticationRecoveryCodes(): ?array;
    public function saveAppAuthenticationRecoveryCodes(?array $codes): void;
  3. AdminPanelProvider:
    ->multiFactorAuthentication([
        AppAuthentication::make()->recoverable(),
    ])
    ->requiresMultiFactorAuthentication()   // Pflicht für alle Admins
  4. Filament rendert automatisch:

Vorteile

Nachteile / Risiken

Aufwand


3 — Option B: Passkey / WebAuthn / FIDO2

Plugin-Landschaft (composer-search-Ergebnis)

PaketFilament-VersionMainline-StandNotiz
jeffersongoncalves/filament-multifactor-passkeys„Filament 5 multi-factor“unbekanntKlingt am nächsten am Ziel — Audit nötig
marcelweidum/filament-passkeysunbekanntCommunity 
statview/filament-passkeysunbekanntCommunity 
Eigenbau auf web-auth/webauthn-lib + Filament-Hooksn/amature libvolle Kontrolle, hoher Aufwand

Keiner dieser Plugins ist offiziell von Filament gewartet. Filament 5 hat kein natives Passkey-Modul (nur App-TOTP + Email).

Mechanik (vereinfacht)

  1. User-Tabelle bekommt neue webauthn_credentials Tabelle (1:n: credential_id, public_key, sign_count, transports, attestation, created_at).
  2. Enrollment-Flow:
  3. Login-Flow:

Vorteile

Nachteile / Blocker

Aufwand


4 — Vergleichsmatrix

KriteriumOption A: TOTPOption B: Passkey/WebAuthn
Sicherheits-NiveauMittel (HOTP/TOTP-Standard RFC 6238)Hoch (FIDO2, origin-bound)
Phishing-Resistenz replay-fähig im 30s-Window origin-bound, nicht phishable
Implementierungs-Aufwand 2–3h (Filament-native) 12–20h (inkl. HTTPS)
Lockout-RisikoNiedrig (Recovery-Codes built-in)Mittel (eigener Recovery-Flow nötig)
Rollback-Risiko rein additive MigrationMittel (neue Tabelle, JS-Hooks)
Testbarkeit Google2FA deterministisch Browser-API, schwerer zu testen
HTTPS-Vorbedingung keineHARTE Pflicht (Blocker H5)
Recovery / UXRecovery-Codes + Re-SetupRecovery-Codes selbst implementieren
Audit-SurfaceKlein (Filament-internes Modul)Groß (Community-Plugin oder webauthn-lib)
Operator-UXAuthenticator-App, ~10s Code1-Tap Biometrie (wenn Setup okay)
Composer-Pakete neu01–2 (Plugin + ggf. lib)
Roadmap-WertKurzfristig pragmatischStrategisch + premium
Phasen-Risiko (MH-5b/c/d Block)NiedrigHoch

5 — Vier Architektur-Varianten

Variante A — TOTP-first only

Variante B — Passkey-first only

Variante C — Beide parallel (User wählt selbst)

Variante D — Staged: TOTP jetzt, Passkey später (BACKLOG) EMPFEHLUNG


6 — Sicherheits-Anforderungen (verbindlich für SEC-1b-6)

Req-IDAnforderungerfüllt von
MFA-R1MFA Pflicht für alle UserRole::AdminrequiresMultiFactorAuthentication() im AdminPanelProvider
MFA-R2Kein Bypass via php artisan tinker / Eloquent-Direkt-Edit (außer Notfall-Reset durch DB-Admin)dokumentiert + audit-log auf reset-event (BACKLOG)
MFA-R3Secrets niemals in Logs / Telegram / PDF / GUIencrypted column + nie in dd()/Log::info()
MFA-R4Recovery-Codes einmalig nutzbar, encrypted at restFilament-default
MFA-R5Lockout-Pfad dokumentiert (Operator-Runbook)SOP: DB-direkt-NULL der app_authentication_secret-Spalte mit Audit-Log
MFA-R6MFA-Flow respektiert MAX_LOGIN_ATTEMPTS=3 (SEC-1b-5)Throttle bleibt auf 1st-Step; 2nd-Step bekommt eigenen Throttle
MFA-R7MFA-Setup-Page nur post-Login, nie publicFilament-default (Profil-Page ist auth-required)
MFA-R8TESTNET-Banner / Mainnet-Block bleiben ungetouchedreine GUI-Auth-Layer-Änderung
MFA-R9Test-Coverage: Setup / Login-Step / Recovery-Code / Failed-Code / Disabled-User≥10 PHPUnit-Tests via Safe-Runner
MFA-R10Keine Bot-Code- / Worker- / Watchdog-Berührungrein GUI-Layer
MFA-R11Backup vor Migration (durable rule: pg_dump + state-snapshot)Pflicht-Schritt im Implementations-Plan
MFA-R12Restart-Anforderung dokumentiert (web-server reload reicht; kein Bot/Worker)klar abgegrenzt

7 — Empfehlung

Variante D — Staged (TOTP-first jetzt, Passkey post-HTTPS später).

Begründung

  1. Filament 5 native TOTP + bereits installierte pragmarx/google2fa{,-qrcode} reduzieren Implementierungs-Risiko auf nahezu Null.
  2. HTTPS-Blocker (SEC-1a H5): Passkey braucht zwingend HTTPS mit gültigem Zertifikat. APP_URL=http://127.0.0.1:8090 ist heute Showstopper. Diese Infrastruktur-Vorbedingung (Let's Encrypt + Domain) gehört in eine eigene SEC-1c-Phase, nicht in SEC-1b-6.
  3. MH-5b/c/d Operator-Wert: Approve / Reject / Pause / Resume / Release sind blockiert bis MFA da ist. TOTP unblockt diesen Pfad innerhalb von 2–3h.
  4. Operator-Realität: 1-Admin-Setup; Passkey als sole-factor wäre Lockout-anfälliger als TOTP+Recovery-Codes.
  5. Phishing-Restrisiko mit TOTP ist im TESTNET-only-Setup mit MAX_LOGIN_ATTEMPTS=3 + fail2ban + 169-IP-Banlist akzeptabel, solange Mainnet hard-blocked bleibt.
  6. Passkey als BACKLOG-Phase SEC-1d bleibt offen, sobald SEC-1c (HTTPS/Let's Encrypt) live ist.

NO-GO-Bedingungen für SEC-1b-6

Phasen-Sequenz (Vorschlag)

PhaseInhaltBlock für
SEC-1b-6 (Variante D Step 1)TOTP-MFA Filament-native, 2 DB-cols, Recovery-Codes, ~10 Testsunblockt MH-5b/c/d
MH-5bRequest + Reject Actionsnach SEC-1b-6
MH-5cApprove-Wizard 5 Stepsnach SEC-1b-6
MH-5dPause/Resume/Release Actionsnach SEC-1b-6
SEC-1cDB-Privs / Let's Encrypt / Admin / Session-Encryptparallel zu MH-5x erlaubt
SEC-1d (BACKLOG)Passkey/WebAuthn als zusätzlicher Faktor (Variante D Step 2)nach SEC-1c HTTPS + Domain
MH-6Worker-Handler für 8 CommandTypesnach MH-5 + SEC-1b-6
MH-7Bot-Wiring (Restart!)nach SEC-1c

8 — Implementierungs-Skizze für Variante D Step 1 (TOTP) — NUR PLAN

Geliefert würde (im späteren Implementations-Patch, nicht jetzt):

  1. Migration users add 2 columns:
  2. User-Modell implementiert HasAppAuthentication + HasAppAuthenticationRecovery; 2 encrypted casts.
  3. AdminPanelProvider:
    ->multiFactorAuthentication([
        \Filament\Auth\MultiFactor\App\AppAuthentication::make()->recoverable(),
    ])
    ->requiresMultiFactorAuthentication()
  4. Login-Page: keine Änderung. 2nd-step wird von Filament automatisch eingehängt.
  5. Operator-Runbook: docs/ops/sec_1b_6_mfa_runbook.md mit Setup-Flow, Recovery-Code-Storage-Empfehlung, Lockout-Reset-SOP.
  6. Tests (≥10) via Safe-Runner:
  7. Backup: pg_dump tradingbot_gui + .env + state-snapshot VOR Migration.

Drift-Audit-Liste (vor docker cp / Restart — durable rule)


9 — Operator-Entscheidungs-Punkte

Bevor SEC-1b-6 Code-Phase startet, GO/NO-GO erforderlich auf:

  1. Variante A / B / C / D — Empfehlung: D.
  2. Recovery-Code-Anzahl: 8 (Filament-default) ?
  3. Enrollment-Strategy für bestehenden Admin-User: Empfehlung: (a) — wir haben nur 1 Admin, sofortige Enrollment unkritisch.
  4. Lockout-Reset-Pfad: DB-direkt + Audit-Log-Eintrag — okay?
  5. Telegram-Notification bei MFA-Setup / Lockout-Reset: ja (durable rule SEC) oder nein?
  6. SEC-1c (HTTPS/Let's Encrypt) als nächste SEC-Phase parallel oder erst nach MH-5d?

Status: PLAN-REVIEW Plan fertig. Warte auf Operator-GO für Variante + Antworten auf Punkte 1–6.
Kein Code geschrieben. Kein git / docker / test-Touch durchgeführt — pure analysis only.