Filterbare Ansicht, CSV, optionale Weiterleitung an Syslog.
Aufgaben
/protokoll statt Platzhalter, jede Rolle liest: Tabelle mit Zeitpunkt (TT.MM.JJJJ HH:MM:SS), Aktion (lesbar, farbig), Akteur, Host, Zielbenutzer, Fingerprint (gekürzt), Ergebnis; unter md Karten
Zeile aufklappbar: Diff im Diff-Box-Stil, Details als Liste (Werte als JSON), Hash und Vorgänger-Hash
Lesbare Texte für alle Aktionen in src/lib/protokoll-aktionen.ts, gruppiert (Anmeldung, Host-Key, Ausrollen, Schlüssel, Widerruf/Rotation, Zielkonto, Abgleich, Hosts, Personen und Vorlagen, Protokoll)
50 je Seite, „Ältere laden“ hängt per Server Action an; Cursor über id, kein OFFSET; ?vor=<id> als Einstieg
Kopfzeile mit Anzahl und Syslog-Ziel; „Kette prüfen“ (Server Action) mit Ergebnis-Zwischenspeicher für 5 Minuten, Warnung mit Link auf die erste fehlerhafte ID
CSV-Export /api/protokoll.csv: eigene Rechteprüfung, gleiche Filter, gestreamt in Stapeln zu 500, Formel-Entschärfung über src/lib/csv.ts, Export selbst als protokoll.exportiert protokolliert
Kein Lösch-/Bearbeitungsweg; struktureller Test gegen protokoll.update/delete… und UPDATE/DELETE/TRUNCATE "Protokoll" in src/
Syslog nach RFC 5424 (src/lib/syslog.ts, UDP oder TCP mit Oktettzählung, ohne neue Abhängigkeit), eingehängt in protokollieren() nach dem Schreiben
.env.example und docker-compose.yml (web und worker) um SSHKV_SYSLOG_*
Kettenprüfung nur auf Knopfdruck, 5 Minuten zwischengespeichert (je Prozess).protokoll_kette_pruefen() rechnet SHA-256 über jede Zeile und wächst linear mit dem Protokoll; beim bloßen Seitenaufruf wäre das bei 100 000 Einträgen spürbar. Gleichzeitige Klicks teilen sich eine laufende Prüfung. Ein Bruch wird selbst als protokoll.kette_beschaedigt (FEHLER) protokolliert, damit er auch beim Syslog ankommt.
CSV gestreamt über einen ReadableStream mit pull: je Stapel 500 Zeilen (Cursor über id), der nächste Stapel erst, wenn der Client den vorigen abgenommen hat. Der Exporteintrag wird vor dem ersten Byte geschrieben – scheitert er, gibt es keinen Export.
IDs sind nicht lückenlos (Spalten-Default und Trigger ziehen beide aus der Sequenz); Cursor und Tests verlassen sich nur auf die Ordnung.
Syslog: RFC 5424, SD-ID sshkv@32473, Parameter id/akteur/aktion/ergebnis/host/zielbenutzer/fingerprint/hash (escaped nach §6.3.3, Steuerzeichen ersetzt, je Wert ≤ 120 Byte, Zeile ≤ 2048 Byte), MSGID = Aktion, Severity ERFOLG=notice, VERWEIGERT=warning, FEHLER=err, Facility standardmäßig authpriv (SSHKV_SYSLOG_FACILITY). Diff und Details gehen nie hinaus. Fire-and-forget nach dem create; innerhalb einer Transaktion kann ein späterer Rollback eine Syslog-Zeile ohne Gegenstück hinterlassen – das ist die harmlosere Richtung (ihr Hash fehlt dann in der Kette).
--ok nur für erfolgreiche Aktionen, die etwas ändern; Anmeldungen, Abrufe und Export bleiben neutral, Fehler/Verweigert immer --danger.
Quelle: docs/issues/027-protokoll-ansicht.md – dort wird dieses Issue gepflegt.
## Ziel
Filterbare Ansicht, CSV, optionale Weiterleitung an Syslog.
## Aufgaben
- [x] `/protokoll` statt Platzhalter, jede Rolle liest: Tabelle mit Zeitpunkt (TT.MM.JJJJ HH:MM:SS), Aktion (lesbar, farbig), Akteur, Host, Zielbenutzer, Fingerprint (gekürzt), Ergebnis; unter `md` Karten
- [x] Zeile aufklappbar: Diff im Diff-Box-Stil, Details als Liste (Werte als JSON), Hash und Vorgänger-Hash
- [x] Lesbare Texte für alle Aktionen in `src/lib/protokoll-aktionen.ts`, gruppiert (Anmeldung, Host-Key, Ausrollen, Schlüssel, Widerruf/Rotation, Zielkonto, Abgleich, Hosts, Personen und Vorlagen, Protokoll)
- [x] Filter per GET: Zeitraum (Berliner Kalendertage), Aktionsgruppe, Akteur, Host, Ergebnis, Freitext (Fingerprint/Host/Benutzer)
- [x] 50 je Seite, „Ältere laden“ hängt per Server Action an; Cursor über `id`, kein `OFFSET`; `?vor=<id>` als Einstieg
- [x] Kopfzeile mit Anzahl und Syslog-Ziel; „Kette prüfen“ (Server Action) mit Ergebnis-Zwischenspeicher für 5 Minuten, Warnung mit Link auf die erste fehlerhafte ID
- [x] CSV-Export `/api/protokoll.csv`: eigene Rechteprüfung, gleiche Filter, gestreamt in Stapeln zu 500, Formel-Entschärfung über `src/lib/csv.ts`, Export selbst als `protokoll.exportiert` protokolliert
- [x] Kein Lösch-/Bearbeitungsweg; struktureller Test gegen `protokoll.update/delete…` und `UPDATE/DELETE/TRUNCATE "Protokoll"` in `src/`
- [x] Syslog nach RFC 5424 (`src/lib/syslog.ts`, UDP oder TCP mit Oktettzählung, ohne neue Abhängigkeit), eingehängt in `protokollieren()` nach dem Schreiben
- [x] `.env.example` und `docker-compose.yml` (web und worker) um `SSHKV_SYSLOG_*`
- [x] Tests: Query/Cursor/Filter, CSV-Route, Kettenprüfung, Syslog (Format, Escaping, Länge, UDP-/TCP-Empfänger), Aktionstexte, Struktur; E2E `tests/e2e/protokoll.spec.ts`
- [x] Screenshots `protokoll-desktop.png` und `protokoll-mobil.png`
## Akzeptanzkriterien
- [x] Jede `aktion: "…"` im Quellcode hat einen lesbaren Text (Test)
- [x] Filter und „Ältere laden“ liefern weder Lücken noch Doppelte, auch wenn zwischendurch Einträge dazukommen
- [x] CSV ohne Sitzung → 403; Kopfzeile `id;zeitpunkt;akteur;aktion;…;hash`; große Protokolle werden in Stapeln gelesen
- [x] Manipulierte Zeile → Warnung mit ID; unversehrte Kette → „Hash-Kette unversehrt“
- [x] Ausgefallener Syslog-Server verhindert keine Aktion; Fehler höchstens einmal je Minute im Log
- [x] 1440 und 390 px ohne Querscrollen
## Abhängigkeiten
#005
## Notizen / Entscheidungen
- **Kettenprüfung nur auf Knopfdruck, 5 Minuten zwischengespeichert (je Prozess).** `protokoll_kette_pruefen()` rechnet SHA-256 über jede Zeile und wächst linear mit dem Protokoll; beim bloßen Seitenaufruf wäre das bei 100 000 Einträgen spürbar. Gleichzeitige Klicks teilen sich eine laufende Prüfung. Ein Bruch wird selbst als `protokoll.kette_beschaedigt` (FEHLER) protokolliert, damit er auch beim Syslog ankommt.
- **CSV gestreamt** über einen `ReadableStream` mit `pull`: je Stapel 500 Zeilen (Cursor über `id`), der nächste Stapel erst, wenn der Client den vorigen abgenommen hat. Der Exporteintrag wird vor dem ersten Byte geschrieben – scheitert er, gibt es keinen Export.
- **IDs sind nicht lückenlos** (Spalten-Default und Trigger ziehen beide aus der Sequenz); Cursor und Tests verlassen sich nur auf die Ordnung.
- **Syslog:** RFC 5424, SD-ID `sshkv@32473`, Parameter id/akteur/aktion/ergebnis/host/zielbenutzer/fingerprint/hash (escaped nach §6.3.3, Steuerzeichen ersetzt, je Wert ≤ 120 Byte, Zeile ≤ 2048 Byte), MSGID = Aktion, Severity ERFOLG=notice, VERWEIGERT=warning, FEHLER=err, Facility standardmäßig `authpriv` (`SSHKV_SYSLOG_FACILITY`). Diff und Details gehen nie hinaus. Fire-and-forget nach dem `create`; innerhalb einer Transaktion kann ein späterer Rollback eine Syslog-Zeile ohne Gegenstück hinterlassen – das ist die harmlosere Richtung (ihr Hash fehlt dann in der Kette).
- `--ok` nur für erfolgreiche Aktionen, die etwas ändern; Anmeldungen, Abrufe und Export bleiben neutral, Fehler/Verweigert immer `--danger`.
---
Quelle: `docs/issues/027-protokoll-ansicht.md` – dort wird dieses Issue gepflegt.
florian.wilde
added this to the v0.5.0 milestone 2026-10-12 15:12:48 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Ziel
Filterbare Ansicht, CSV, optionale Weiterleitung an Syslog.
Aufgaben
/protokollstatt Platzhalter, jede Rolle liest: Tabelle mit Zeitpunkt (TT.MM.JJJJ HH:MM:SS), Aktion (lesbar, farbig), Akteur, Host, Zielbenutzer, Fingerprint (gekürzt), Ergebnis; untermdKartensrc/lib/protokoll-aktionen.ts, gruppiert (Anmeldung, Host-Key, Ausrollen, Schlüssel, Widerruf/Rotation, Zielkonto, Abgleich, Hosts, Personen und Vorlagen, Protokoll)id, keinOFFSET;?vor=<id>als Einstieg/api/protokoll.csv: eigene Rechteprüfung, gleiche Filter, gestreamt in Stapeln zu 500, Formel-Entschärfung übersrc/lib/csv.ts, Export selbst alsprotokoll.exportiertprotokolliertprotokoll.update/delete…undUPDATE/DELETE/TRUNCATE "Protokoll"insrc/src/lib/syslog.ts, UDP oder TCP mit Oktettzählung, ohne neue Abhängigkeit), eingehängt inprotokollieren()nach dem Schreiben.env.exampleunddocker-compose.yml(web und worker) umSSHKV_SYSLOG_*tests/e2e/protokoll.spec.tsprotokoll-desktop.pngundprotokoll-mobil.pngAkzeptanzkriterien
aktion: "…"im Quellcode hat einen lesbaren Text (Test)id;zeitpunkt;akteur;aktion;…;hash; große Protokolle werden in Stapeln gelesenAbhängigkeiten
#005
Notizen / Entscheidungen
protokoll_kette_pruefen()rechnet SHA-256 über jede Zeile und wächst linear mit dem Protokoll; beim bloßen Seitenaufruf wäre das bei 100 000 Einträgen spürbar. Gleichzeitige Klicks teilen sich eine laufende Prüfung. Ein Bruch wird selbst alsprotokoll.kette_beschaedigt(FEHLER) protokolliert, damit er auch beim Syslog ankommt.ReadableStreammitpull: je Stapel 500 Zeilen (Cursor überid), der nächste Stapel erst, wenn der Client den vorigen abgenommen hat. Der Exporteintrag wird vor dem ersten Byte geschrieben – scheitert er, gibt es keinen Export.sshkv@32473, Parameter id/akteur/aktion/ergebnis/host/zielbenutzer/fingerprint/hash (escaped nach §6.3.3, Steuerzeichen ersetzt, je Wert ≤ 120 Byte, Zeile ≤ 2048 Byte), MSGID = Aktion, Severity ERFOLG=notice, VERWEIGERT=warning, FEHLER=err, Facility standardmäßigauthpriv(SSHKV_SYSLOG_FACILITY). Diff und Details gehen nie hinaus. Fire-and-forget nach demcreate; innerhalb einer Transaktion kann ein späterer Rollback eine Syslog-Zeile ohne Gegenstück hinterlassen – das ist die harmlosere Richtung (ihr Hash fehlt dann in der Kette).--oknur für erfolgreiche Aktionen, die etwas ändern; Anmeldungen, Abrufe und Export bleiben neutral, Fehler/Verweigert immer--danger.Quelle:
docs/issues/027-protokoll-ansicht.md– dort wird dieses Issue gepflegt.