Add AUTH_DEV_AUTOLOGIN to switch off the login on development instances

With AUTH_DEV_AUTOLOGIN=<username>, every /api request without a valid
session runs as that existing, active user and skips the forced password
change. Unset keeps the normal login; unknown or deactivated users still
get 401, real sessions take precedence, the CSRF application header stays
mandatory and the API logs a warning at startup. The switch is not
limited to localhost because the development instance is reached from
other machines and through a reverse proxy (THREATMODEL D2/R15). It must
never be set on an instance with real project data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Julian Appel 2026-10-30 09:03:29 +01:00
parent 4677b1685c
commit 084002bea9
11 changed files with 211 additions and 8 deletions

View file

@ -75,6 +75,7 @@ Gesundheitsdaten: keine. Personenbezug: nur Benutzerkonten.
| R12 | Keine Nachvollziehbarkeit bei geteilten Projekten: der Projektverlauf hat `actorId`, die API setzt ihn aber nie | A4 | Änderungen keinem Nutzer zuordenbar | M | angemeldeten Nutzer (`req.authUser`) bis in `projectCommandService` durchreichen | `grep actorId src/server` leer; Spalte `project_revisions.actor_id` | **offen** |
| R13 | Secrets oder echte Kundendaten im Repo | A6 | Zugangsdaten bzw. Kundendaten öffentlich | H | `.env`/`.env.*` und `docs/spec/kbp-Stromkreis.xlsx` gitignored, Testdaten synthetisch, gitleaks per pre-commit | `.gitignore`; `make secrets` | belegt |
| R14 | Abhängigkeiten (u. a. `exceljs` parst Fremdinhalt) | A6 | Codeausführung, DoS | M | `npm audit` in `make check`, Lockfile, neue Pakete per `dependency-vetting` | `make audit`: 6 moderate ohne nicht-brechenden Fix (`drizzle-kit`/`esbuild`, `exceljs`/`uuid`), kein High/Critical | offen bis Eintrag in `RELEASE-AUSNAHMEN.md` oder Update |
| R15 | Login per `AUTH_DEV_AUTOLOGIN` abgeschaltet, versehentlich auf einer Instanz mit echten Projektdaten gesetzt | A1, A2 | jeder, der die Instanz erreicht, arbeitet mit den Rechten des Auto-Login-Benutzers (bei Admin: inkl. Benutzerverwaltung) | H | Standard leer, nur ein vorhandener aktiver Benutzer wird verwendet (sonst 401), echte Sessions haben Vorrang, Warnung im API-Log beim Start, CSRF-Header bleibt Pflicht. Bewusst **nicht** auf localhost begrenzt (**D2**) | `tests/authentication.test.ts` „development auto-login“; Baseline „jede Route verlangt Login“ läuft ohne den Schalter | belegt für den Schalter selbst; Schutz der Live-Instanz hängt an deren `.env` (dort nie setzen) |
## Design-Entscheidungen
@ -95,6 +96,16 @@ nichts als entschieden ein.
- Folge: ASVS-light B1/B2 sind für diese Instanz nicht anwendbar (R3). `idorGap` in
`tests/security/security.config.ts` bleibt gesetzt und macht den Ist-Zustand sichtbar.
**D2: Entwicklungsinstanz ohne Login (`AUTH_DEV_AUTOLOGIN`).**
- Aussage von: Julian im Chat mit einem Agenten am 30.10.2026 („Deaktiviere mal den login auf
dieser dev instanz. Der ist hier nicht nötig“; Schalter ausdrücklich „nicht auf localhost
begrenzen, da ich von anderen PCs und Netzen drauf zugreife. Eventuell auch mit
reverseproxy“). Eingetragen von diesem Agenten.
- Gilt für: lokale Entwicklungsinstanzen ohne echte Projektdaten. Nie auf cj-ki oder einer
anderen Instanz mit Kundendaten.
- Folge: R15. Auf solchen Instanzen ist der Login aus; wer die Instanz erreicht, arbeitet mit
den Rechten des konfigurierten Benutzers.
## Offene Entscheidungen
E1 (geteilte Projekte) ist mit D1 beantwortet.

View file

@ -69,6 +69,26 @@ Verknüpfung mit einer Mitarbeiter-/Personen-Stammdatentabelle.
Klartext durchs Netz. Für Zugriff außerhalb des LANs HTTPS über einen
Reverse-Proxy vorschalten und `COOKIE_SECURE=true` setzen.
## Entwicklungsinstanz ohne Login
`AUTH_DEV_AUTOLOGIN=<benutzername>` schaltet den Login für eine
Entwicklungsinstanz ab (Entscheidung Julian, 2026-10-30): Jede `/api`-Anfrage
ohne gültige Session läuft als dieser vorhandene, aktive Benutzer, auch der
Passwortwechsel-Zwang entfällt. Der Schalter ist bewusst nicht auf localhost
begrenzt, weil die Dev-Instanz von anderen Rechnern und über einen
Reverse-Proxy erreicht wird. Jeder, der die Instanz erreicht, hat damit die
Rechte dieses Benutzers. Leer (Standard) gilt der normale Login; ein
unbekannter oder deaktivierter Benutzer führt weiter zu 401. Echte Sessions
haben Vorrang, und die API protokolliert beim Start eine Warnung. Der
CSRF-Anwendungsheader bleibt Pflicht. Auf einer Instanz mit echten
Projektdaten darf der Schalter nie gesetzt sein.
```dotenv
AUTH_BOOTSTRAP_USERNAME=julian
AUTH_BOOTSTRAP_PASSWORT=<Startpasswort, mindestens 12 Zeichen>
AUTH_DEV_AUTOLOGIN=julian
```
## Bootstrap-Admin
`AUTH_BOOTSTRAP_USERNAME` / `AUTH_BOOTSTRAP_PASSWORT` (Env-Variablen, siehe