> DATA ARCHIVE

Gesicherte Kommunikationsprotokolle

[ Threat Pulse ] Synchronisiere KEV Feed...

Vollartikel

Website-Security in der Praxis: Unsere FastAPI-Architektur mit Passkeys, Step-up und operativer Härtung

Gepostet am: 2026-03-03 17:40

Lesedauer: ca. 4 Min · 741 Wörter

Warum wir Security als System und nicht als Feature behandeln

In produktiven Umgebungen reicht es nicht, nur „Login“ zu bauen. Entscheidend ist eine mehrstufige Sicherheitsarchitektur, die Identität, Zugriff, Session-Schutz, Abuse-Prevention und Betrieb zusammendenkt. Genau darauf basiert unsere FastAPI-Implementierung.

Dieser Artikel zeigt transparent:

  1. wie wir Dienste und Admin-Bereich absichern,
  2. wie Passkeys in FastAPI integriert sind,
  3. wie Step-up-Authentifizierung praktisch umgesetzt wird,
  4. welche Betriebsmaßnahmen (Container, Secrets, Firewall, Monitoring) das Ganze tragen.

1) Grundprinzip: Defense in Depth

Unsere Sicherheit basiert auf mehreren Schichten:

  • Identity Layer: OAuth + Passkeys (WebAuthn)
  • Access Layer: Entitlements, Admin-Guard, optionale IP-Allowlist
  • Session Layer: signierte Session-Cookies mit getrennten Secrets
  • Abuse Layer: Login-Ratelimits, Lockouts, Step-up-Frischefenster
  • Runtime Layer: Secrets via *_FILE, least privilege Container, Healthchecks

So entsteht kein „Single Point of Failure“: Wenn eine Schutzmaßnahme umgangen wird, greifen weitere Kontrollen.


2) FastAPI-Bausteine für sichere Requests

2.1 Zentrale Dependencies

In FastAPI nutzen wir Dependencies, um Sicherheitsregeln zentral durchzusetzen. Dadurch wird Security nicht in jede Route kopiert, sondern über Guards standardisiert erzwungen.

from fastapi import Depends, HTTPException

def admin_guard(...):
    # Basic-Auth + optionale IP/CIDR-Policy + Lockout + Step-up-Status
    ...
    if not allowed:
        raise HTTPException(status_code=403, detail="Forbidden")

@router.get("/admin/users")
async def admin_users_panel(..., admin_user: str = Depends(admin_guard)):
    ...

Vorteil: Jede geschützte Route hat konsistente Regeln und dieselbe Audit-/Fehlerlogik.

2.2 Security Headers zentral im Middleware-Layer

@app.middleware("http")
async def security_headers(request, call_next):
    response = await call_next(request)
    response.headers["X-Content-Type-Options"] = "nosniff"
    response.headers["X-Frame-Options"] = "DENY"
    response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
    response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
    response.headers["Content-Security-Policy"] = "default-src 'self'; ..."
    return response

Damit ist Browser-Schutz nicht optional pro Endpunkt, sondern global aktiv.


3) Passkeys mit FastAPI: Schritt-für-Schritt

Schritt 1: Challenge erzeugen und in Session speichern

Beim Start einer Registrierung oder Authentifizierung erzeugen wir serverseitig eine Challenge. Diese wird kurzlebig in der Session hinterlegt.

challenge = generate_registration_options(...)
request.session["passkey_challenge"] = challenge
return challenge_payload

Schritt 2: Browser/WebAuthn führt Ceremony durch

Im Frontend läuft navigator.credentials.create() (Register) bzw. navigator.credentials.get() (Login).

Schritt 3: Response serverseitig verifizieren

verification = verify_registration_response(
    credential=response,
    expected_challenge=session_challenge,
    expected_origin=origin,
    expected_rp_id=rp_id,
)

Nur wenn Challenge, Origin, RP-ID und Signatur passen, wird das Credential akzeptiert.

Schritt 4: Credential persistieren

Gespeichert werden nur notwendige technische Daten (credential_id, public key, sign_count, Metadaten). Private Schlüssel verlassen das Gerät des Users nie.

Schritt 5: Bei Login sign_count & last_used_at aktualisieren

Nach erfolgreicher Assertion aktualisieren wir den Zähler und Zeitstempel, um Replays und Missbrauchsmuster besser erkennen zu können.


4) Step-up-Authentifizierung für Admin-Aktionen

Nicht jede Session darf sofort kritische Aktionen ausführen. Deshalb nutzen wir Step-up:

  • reguläre Anmeldung für normale Nutzung,
  • zusätzliche Passkey-Bestätigung + Admin-Kontext für sensible Bereiche.

Technisch wird ein kurzer Step-up-Zeitraum (MAX_AGE_SECONDS) gesetzt. Ist er abgelaufen, muss der User erneut bestätigen.

if admin_stepup_required and stepup_age > max_age:
    raise HTTPException(status_code=403, detail="admin step-up required")

Das reduziert Risiko durch gestohlene oder offene Sessions drastisch.


5) Secrets, Runtime und Infrastruktur-Härtung

5.1 Secrets niemals im Klartext deployen

Wir lesen Secrets primär über *_FILE aus /run/secrets:

def get_env(name, default=""):
    direct = os.getenv(name)
    if direct:
        return direct
    file_path = os.getenv(f"{name}_FILE")
    if file_path:
        return Path(file_path).read_text().strip()
    return default

5.2 Least Privilege im Container

  • no-new-privileges:true
  • cap_drop mit gezieltem cap_add nur wenn technisch nötig
  • read_only + tmpfs für stateless Services
  • App läuft als Nicht-Root-User

5.3 Firewall & Exposure

Nur notwendige Ports offen (typisch 22, 80, 443, ggf. 81 für NPM-Admin). Interne Services wie DB bleiben auf private Bindings beschränkt.


6) Monitoring, Recovery und Betriebsrealität

Sicherheit ist erst vollständig, wenn auch Recovery sauber ist:

  • Healthcheck-Endpunkte (/healthz)
  • Instanz-Heartbeat und Monitoring-Übersicht
  • Audit-Logs für Admin-Aktionen
  • Recovery-Skript für Step-up-Freigaben (wenn noch kein berechtigter User existiert)

Damit bleibt das System auch unter Incident-Bedingungen steuerbar.


7) Ergebnis: Sicherheit mit nachvollziehbarer Operabilität

Unsere FastAPI-Architektur kombiniert moderne Authentifizierung (Passkeys) mit produktiver Governance (Step-up, Guardrails, Härtung, Monitoring). Der entscheidende Punkt ist die Transparenz: Sicherheitsregeln sind nachvollziehbar implementiert, reproduzierbar testbar und im Betrieb belastbar.

Wenn ihr ein ähnliches Setup aufbaut, startet mit der Reihenfolge:

  1. zentrale Guards,
  2. Passkey-Flow,
  3. Step-up für kritische Pfade,
  4. Secrets/Runtime-Härtung,
  5. Monitoring + Recovery.

So entsteht ein System, das nicht nur „sicher aussieht“, sondern im Alltag wirklich standhält.

Action Zone

Passkey-geschützte Security-Tools live testen

Setze die Erkenntnisse aus diesem Artikel direkt um – strukturiert, schnell und nachvollziehbar.

Support Skull & Bones