Aufsicht und Eingriff getrennt: neuer Haken "Audit-Betrieb"

Die DSGVO-Rolle trug audit:* komplett, also auch audit:admin. Ein
DSGVO-Beauftragter konnte damit seal-backlog, rehash und cleanup - seine
eigene Beweisgrundlage ersetzen. Wer das Protokoll beaufsichtigt, darf es
nicht umschreiben koennen. Dieselbe Klasse wie R184-02: falsche Domaene,
zu breit gebuendelt.

Der naheliegende Fix waere falsch gewesen. audit:admin einfach aus der
DSGVO-Rolle zu streichen haette es heimatlos gemacht: Die Admin-Rolle ist
ausdruecklich ohne audit/gdpr gebaut, einzige verbleibende Quelle waere
der Entwicklerzugriff - der alles gibt. Prod versiegeln haette dann
Vollzugriff vorausgesetzt.

Deshalb eine eigene versteckte Rolle "Audit-Betrieb" (audit:read +
audit:admin), zugewiesen ueber eine Checkbox wie DSGVO/Entwickler. DSGVO
behaelt audit:read + audit:export + gdpr:*. Fuer kein bestehendes Konto
weitet sich etwas aus; es wird enger, und wer eingreifen koennen soll,
bekommt es ausdruecklich.

Keine zusaetzliche Rechte-Huerde davor, weil das am Henne-Ei-Problem
scheitert: Nach der Aufteilung haelt zunaechst niemand audit:admin,
koennte ihn also auch niemand vergeben. Stattdessen wird die Vergabe
laut - CRITICAL im Protokoll und PERMISSION_CHANGED/CRITICAL im
Alarmkanal, samt Kennzeichen, ob sich jemand den Haken selbst gesetzt hat.

Nebenbei geschlossen: setUserGdprAccess() legte die DSGVO-Rolle im
Notfallpfad mit audit:* komplett an - eine zweite Liste, die dasselbe
bedeuten sollte und die Buendelung stillschweigend zurueckgebracht haette.

ACHTUNG beim Deploy: Bestehende DSGVO-Konten verlieren audit:admin. Wer
Prod versiegeln will, muss sich vorher "Audit-Betrieb" ankreuzen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-26 17:16:27 +02:00
co-authored by Claude Opus 5
parent 909e523634
commit fc6f39eba0
8 changed files with 232 additions and 21 deletions
+29 -3
View File
@@ -93,9 +93,34 @@ async function main() {
// Developer: alles
const developerPermIds = allPermissions.map((p) => p.id);
// DSGVO: audit + gdpr komplett
// DSGVO: Datenschutz-Verwaltung plus LESENDEN Zugriff aufs Audit-Protokoll.
//
// Bewusst OHNE `audit:admin`. Diese Rolle beaufsichtigt das Protokoll - sie
// darf es nicht umschreiben koennen. Mit `audit:admin` haette ein
// DSGVO-Beauftragter `seal-backlog`, `rehash` und `cleanup`, also die Mittel,
// seine eigene Beweisgrundlage zu ersetzen. Wer prueft und wer eingreift,
// sind zwei Rollen (Pentest R186, im Anschluss an R184-02: falsche Domaene,
// zu breit gebuendelt).
const gdprPermIds = allPermissions
.filter((p) => p.resource === 'audit' || p.resource === 'gdpr')
.filter(
(p) =>
p.resource === 'gdpr' ||
(p.resource === 'audit' && (p.action === 'read' || p.action === 'export')),
)
.map((p) => p.id);
// Audit-Betrieb: die eingreifenden Rechte am Protokoll - versiegeln,
// neu berechnen, aufraeumen, Aufbewahrung aendern. Plus `audit:read`, denn
// siegeln zu duerfen ohne das Ergebnis sehen zu koennen waere unbrauchbar.
//
// Eigene versteckte Rolle statt einem Anhaengsel an Admin: So weitet sich
// durch die Umstellung fuer KEIN bestehendes Konto etwas aus. Wer eingreifen
// koennen soll, bekommt es ausdruecklich - und diese Zuweisung ist selbst
// ein sichtbarer Vorgang.
const auditBetriebPermIds = allPermissions
.filter(
(p) => p.resource === 'audit' && (p.action === 'read' || p.action === 'admin'),
)
.map((p) => p.id);
// Gegenbuch: NUR audit:read.
@@ -152,7 +177,8 @@ async function main() {
const rolesSpec: Array<{ name: string; description: string; permIds: number[] }> = [
{ name: 'Admin', description: 'Voller Zugriff auf alle Funktionen', permIds: adminPermIds },
{ name: 'Developer', description: 'Voller Zugriff inkl. Entwickler-Tools', permIds: developerPermIds },
{ name: 'DSGVO', description: 'DSGVO-Zugriff: Audit-Logs und Datenschutz-Verwaltung', permIds: gdprPermIds },
{ name: 'DSGVO', description: 'DSGVO-Zugriff: Audit-Logs lesen und Datenschutz-Verwaltung', permIds: gdprPermIds },
{ name: 'Audit-Betrieb', description: 'Darf das Audit-Protokoll versiegeln, aufräumen und die Aufbewahrung ändern', permIds: auditBetriebPermIds },
{ name: 'Mitarbeiter', description: 'Kann Kunden und Verträge verwalten', permIds: employeePermIds },
{ name: 'Mitarbeiter (Nur-Lesen)', description: 'Kann nur lesen, keine Änderungen', permIds: readOnlyPermIds },
{ name: 'Gegenbuch', description: 'Darf das Audit-Protokoll nur lesen und prüfen sonst nichts', permIds: gegenbuchPermIds },