feat(anmeldung): lokale Benutzerkonten mit Pflicht-TOTP (#035)

Ohne authentik gab es nur den Notfall-Admin – ein geteiltes Konto ohne
Rollen und ohne erkennbare Akteure im Audit-Log. Admins legen jetzt
lokale Konten an; sshkv erzeugt ein Einmal-Passwort, das bei der ersten
Anmeldung ersetzt wird, danach ist TOTP Pflicht.

Rollen, Sperren (beendet Sitzungen sofort) und Zurücksetzen unter
Einstellungen → Benutzer, nur für Admins mit frischer Bestätigung.
SSHKV_LOKALE_KONTEN=0 schaltet lokale Konten ab; der Notfall-Admin
bleibt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 22:36:25 +02:00
co-authored by Claude Opus 5.5
parent d9eec3d991
commit 4219701b29
41 changed files with 1295 additions and 109 deletions
+12
View File
@@ -13,6 +13,7 @@
export const AKTIONSGRUPPEN = {
anmeldung: "Anmeldung",
benutzer: "Benutzer",
hostkey: "Host-Key",
ausrollen: "Ausrollen",
schluessel: "Schlüssel",
@@ -44,6 +45,17 @@ export const AKTIONEN: Readonly<Record<string, Beschreibung>> = {
"anmeldung.oidc.erstmals": a("Erste Anmeldung (OIDC)", "anmeldung"),
"anmeldung.verweigert": a("Anmeldung verweigert", "anmeldung", false),
"anmeldung.notfall": a("Anmeldung Notfall-Admin", "anmeldung", false),
"anmeldung.lokal": a("Anmeldung (lokales Konto)", "anmeldung", false),
"anmeldung.lokal.fehlgeschlagen": a("Anmeldung (lokal) fehlgeschlagen", "anmeldung", false),
"anmeldung.lokal.gesperrt": a("Anmeldung (lokal) gesperrt – zu viele Fehlversuche", "anmeldung", false),
"anmeldung.lokal.totp_falsch": a("Anmeldung (lokal): falscher TOTP-Code", "anmeldung", false),
"konto.passwort_gesetzt": a("Eigenes Passwort gesetzt", "benutzer"),
"konto.totp_eingerichtet": a("TOTP eingerichtet", "anmeldung"),
"benutzer.angelegt": a("Lokales Konto angelegt", "benutzer"),
"benutzer.rolle_geaendert": a("Rolle geändert", "benutzer"),
"benutzer.gesperrt": a("Konto gesperrt", "benutzer"),
"benutzer.entsperrt": a("Konto entsperrt", "benutzer"),
"benutzer.zurueckgesetzt": a("Konto zurückgesetzt (Passwort und TOTP)", "benutzer"),
"anmeldung.notfall.fehlgeschlagen": a("Notfall-Anmeldung fehlgeschlagen", "anmeldung", false),
"anmeldung.notfall.gesperrt": a("Notfall-Anmeldung gesperrt", "anmeldung", false),
"anmeldung.notfall.totp_falsch": a("Notfall-Anmeldung: TOTP falsch", "anmeldung", false),