Enterprise-Backup-, Recovery-, Verification-, Security- und Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme. Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes geht in keine Bewertung als "gut" ein. Umfang (Phasen 0-23): - Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll, Katalogaufbau allein aus den Manifesten — ohne Datenbank - Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck - Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell) - Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive - Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit - Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center, Ransomware-Heuristik (meldet, handelt nie) - Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing - Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository - Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64 Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs. Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md und docs/release-candidate.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
397 lines
20 KiB
PL/PgSQL
397 lines
20 KiB
PL/PgSQL
-- Identität, RBAC, Sessions und Audit (Phase 1).
|
|
--
|
|
-- Grundsätze:
|
|
-- - Passwörter werden ausschließlich als Argon2id-Hash abgelegt (PROMPT.md §41).
|
|
-- - MFA-Secrets liegen verschlüsselt vor, niemals im Klartext (PROMPT.md §12).
|
|
-- - Sessiontokens werden ausschließlich als Hash gespeichert: ein Datenbankleck
|
|
-- erlaubt damit keine Übernahme laufender Sitzungen.
|
|
-- - Audit-Daten sind append-only (SYNCOVA_DATABASE.md §13).
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Benutzer
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE users (
|
|
-- id ist der öffentliche Bezeichner des Benutzers.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- username ist der Anmeldename; er ist eindeutig.
|
|
username TEXT NOT NULL UNIQUE,
|
|
-- email ist optional, aber falls gesetzt eindeutig.
|
|
email TEXT UNIQUE,
|
|
-- password_hash enthält den Argon2id-Hash im PHC-Format inklusive Parametern.
|
|
-- NULL bedeutet: der Benutzer besitzt (noch) kein Passwort.
|
|
password_hash TEXT,
|
|
-- status steuert, ob eine Anmeldung möglich ist.
|
|
status TEXT NOT NULL DEFAULT 'active',
|
|
-- mfa_enabled meldet, ob mindestens ein zweiter Faktor aktiv ist.
|
|
mfa_enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
-- failed_login_attempts zählt aufeinanderfolgende Fehlversuche (Brute-Force-Schutz).
|
|
failed_login_attempts INTEGER NOT NULL DEFAULT 0,
|
|
-- locked_until sperrt die Anmeldung bis zu diesem Zeitpunkt.
|
|
locked_until TIMESTAMPTZ,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- updated_at ist der Zeitpunkt der letzten Änderung in UTC.
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- last_login_at ist der Zeitpunkt der letzten erfolgreichen Anmeldung.
|
|
last_login_at TIMESTAMPTZ,
|
|
-- deleted_at kennzeichnet eine weiche Löschung; die Historie bleibt auditierbar.
|
|
deleted_at TIMESTAMPTZ,
|
|
|
|
-- Nur definierte Zustände sind zulässig; ein Tippfehler darf keinen
|
|
-- unbeabsichtigt zugriffsberechtigten Benutzer erzeugen.
|
|
CONSTRAINT users_status_valid CHECK (status IN ('active', 'disabled', 'locked'))
|
|
);
|
|
|
|
COMMENT ON TABLE users IS 'Benutzerkonten der Control Plane. Passwörter ausschließlich als Argon2id-Hash.';
|
|
COMMENT ON COLUMN users.password_hash IS 'Argon2id-Hash im PHC-Format. Niemals ein Klartextpasswort.';
|
|
|
|
-- Aktive Benutzer werden bei jeder Anmeldung gesucht.
|
|
CREATE INDEX users_status_idx ON users (status) WHERE deleted_at IS NULL;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Zweiter Faktor
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE user_mfa_methods (
|
|
-- id ist der Bezeichner der MFA-Methode.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- user_id verweist auf den Besitzer.
|
|
user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
-- type benennt das Verfahren. V1 unterstützt totp; webauthn folgt später.
|
|
type TEXT NOT NULL,
|
|
-- secret_ciphertext ist das mit dem Datenschlüssel verschlüsselte Secret.
|
|
secret_ciphertext BYTEA NOT NULL,
|
|
-- key_version benennt den verwendeten Schlüssel und ermöglicht Rotation (PROMPT.md §143).
|
|
key_version TEXT NOT NULL,
|
|
-- enabled meldet, ob die Methode die Bestätigung durchlaufen hat.
|
|
-- Eine unbestätigte Methode darf keine Anmeldung ermöglichen.
|
|
enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
-- last_used_time_step ist der zuletzt akzeptierte TOTP-Zeitschritt.
|
|
-- Er verhindert die Wiederverwendung eines abgefangenen Codes.
|
|
last_used_time_step BIGINT,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- confirmed_at ist der Zeitpunkt der erfolgreichen Bestätigung.
|
|
confirmed_at TIMESTAMPTZ,
|
|
|
|
CONSTRAINT user_mfa_methods_type_valid CHECK (type IN ('totp')),
|
|
-- Je Verfahren genügt eine Methode pro Benutzer.
|
|
CONSTRAINT user_mfa_methods_unique_per_type UNIQUE (user_id, type)
|
|
);
|
|
|
|
COMMENT ON TABLE user_mfa_methods IS 'Zweite Faktoren je Benutzer. Secrets ausschließlich verschlüsselt.';
|
|
COMMENT ON COLUMN user_mfa_methods.last_used_time_step IS 'Verhindert die Wiederverwendung eines bereits benutzten TOTP-Codes.';
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Wiederherstellungscodes
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE user_recovery_codes (
|
|
-- id ist der Bezeichner des Codes.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- user_id verweist auf den Besitzer.
|
|
user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
-- code_hash ist der Argon2id-Hash des Codes. Der Klartext existiert nur einmal
|
|
-- bei der Ausgabe an den Benutzer (PROMPT.md §43).
|
|
code_hash TEXT NOT NULL,
|
|
-- used_at ist der Zeitpunkt der Verwendung; ein Code gilt genau einmal.
|
|
used_at TIMESTAMPTZ,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
COMMENT ON TABLE user_recovery_codes IS 'Einmalige Wiederherstellungscodes für den Verlust des zweiten Faktors.';
|
|
|
|
CREATE INDEX user_recovery_codes_user_idx ON user_recovery_codes (user_id) WHERE used_at IS NULL;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Rollen und Berechtigungen
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE roles (
|
|
-- id ist der Bezeichner der Rolle.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- name ist der eindeutige technische Name, z. B. backup_operator.
|
|
name TEXT NOT NULL UNIQUE,
|
|
-- description erklärt den Zweck der Rolle in der Oberfläche.
|
|
description TEXT,
|
|
-- is_system kennzeichnet mitgelieferte Rollen. Sie dürfen nicht gelöscht werden,
|
|
-- da sonst bestehende Zuweisungen ihre Bedeutung verlören.
|
|
is_system BOOLEAN NOT NULL DEFAULT FALSE,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- updated_at ist der Zeitpunkt der letzten Änderung in UTC.
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
COMMENT ON TABLE roles IS 'Rollen der rollenbasierten Zugriffssteuerung.';
|
|
|
|
CREATE TABLE permissions (
|
|
-- id ist der Bezeichner der Berechtigung.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- name ist der eindeutige technische Name im Format bereich.aktion.
|
|
name TEXT NOT NULL UNIQUE,
|
|
-- description erklärt, was die Berechtigung erlaubt.
|
|
description TEXT NOT NULL
|
|
);
|
|
|
|
COMMENT ON TABLE permissions IS 'Einzelberechtigungen im Format bereich.aktion.';
|
|
|
|
CREATE TABLE role_permissions (
|
|
-- role_id verweist auf die Rolle.
|
|
role_id UUID NOT NULL REFERENCES roles (id) ON DELETE CASCADE,
|
|
-- permission_id verweist auf die Berechtigung.
|
|
permission_id UUID NOT NULL REFERENCES permissions (id) ON DELETE CASCADE,
|
|
|
|
PRIMARY KEY (role_id, permission_id)
|
|
);
|
|
|
|
CREATE TABLE user_roles (
|
|
-- user_id verweist auf den Benutzer.
|
|
user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
-- role_id verweist auf die zugewiesene Rolle.
|
|
role_id UUID NOT NULL REFERENCES roles (id) ON DELETE RESTRICT,
|
|
-- assigned_at ist der Zeitpunkt der Zuweisung in UTC.
|
|
assigned_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
|
|
PRIMARY KEY (user_id, role_id)
|
|
);
|
|
|
|
COMMENT ON TABLE user_roles IS 'Zuordnung von Benutzern zu Rollen. ON DELETE RESTRICT schützt vor dem Löschen benutzter Rollen.';
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Sitzungen
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE sessions (
|
|
-- id ist der Bezeichner der Sitzung.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- user_id verweist auf den angemeldeten Benutzer.
|
|
user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
-- access_token_hash ist der SHA-256-Hash des Zugriffstokens.
|
|
-- Der Klartext verlässt den Server nur einmal in der Anmeldeantwort.
|
|
access_token_hash TEXT NOT NULL UNIQUE,
|
|
-- refresh_token_hash ist der SHA-256-Hash des Erneuerungstokens.
|
|
refresh_token_hash TEXT NOT NULL UNIQUE,
|
|
-- access_expires_at ist die Ablaufzeit des Zugriffstokens in UTC.
|
|
access_expires_at TIMESTAMPTZ NOT NULL,
|
|
-- refresh_expires_at ist die Ablaufzeit des Erneuerungstokens in UTC.
|
|
refresh_expires_at TIMESTAMPTZ NOT NULL,
|
|
-- revoked_at kennzeichnet eine widerrufene Sitzung (Abmeldung, Sperre, Rotation).
|
|
revoked_at TIMESTAMPTZ,
|
|
-- ip_address ist die Herkunft der Anmeldung.
|
|
ip_address INET,
|
|
-- user_agent ist die Kennung des verwendeten Programms.
|
|
user_agent TEXT,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
-- last_used_at ist der Zeitpunkt der letzten Verwendung in UTC.
|
|
last_used_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
COMMENT ON TABLE sessions IS 'Aktive Sitzungen. Tokens ausschließlich als Hash gespeichert, damit ein Datenbankleck keine Sitzungsübernahme erlaubt.';
|
|
|
|
-- Jeder authentifizierte Request schlägt über den Token-Hash nach.
|
|
CREATE INDEX sessions_user_idx ON sessions (user_id) WHERE revoked_at IS NULL;
|
|
CREATE INDEX sessions_access_expiry_idx ON sessions (access_expires_at) WHERE revoked_at IS NULL;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- MFA-Anmeldeversuche
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE mfa_challenges (
|
|
-- id ist der Bezeichner der Herausforderung und wird dem Client mitgeteilt.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- user_id verweist auf den Benutzer, dessen Passwort bereits stimmte.
|
|
user_id UUID NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
|
-- expires_at begrenzt die Gültigkeit; eine offene Herausforderung ist ein Risiko.
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
-- attempts zählt die Fehlversuche dieser Herausforderung.
|
|
attempts INTEGER NOT NULL DEFAULT 0,
|
|
-- consumed_at kennzeichnet die bereits eingelöste Herausforderung.
|
|
consumed_at TIMESTAMPTZ,
|
|
-- ip_address ist die Herkunft des Anmeldeversuchs.
|
|
ip_address INET,
|
|
-- created_at ist der Anlagezeitpunkt in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
COMMENT ON TABLE mfa_challenges IS 'Offene MFA-Anmeldeversuche zwischen Passwortprüfung und zweitem Faktor.';
|
|
|
|
CREATE INDEX mfa_challenges_expiry_idx ON mfa_challenges (expires_at) WHERE consumed_at IS NULL;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Audit
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
CREATE TABLE audit_events (
|
|
-- id ist der Bezeichner des Ereignisses.
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
-- user_id verweist auf den Handelnden. NULL bei fehlgeschlagener Anmeldung
|
|
-- eines unbekannten Kontos oder bei Systemvorgängen.
|
|
user_id UUID REFERENCES users (id) ON DELETE SET NULL,
|
|
-- actor_username hält den Anmeldenamen fest. Er bleibt erhalten, auch wenn
|
|
-- der Benutzer später gelöscht wird - sonst verlöre das Protokoll seine Aussage.
|
|
actor_username TEXT,
|
|
-- action benennt die Handlung, z. B. USER_LOGIN oder DELETE_JOB.
|
|
action TEXT NOT NULL,
|
|
-- entity_type benennt die Art des betroffenen Objekts.
|
|
entity_type TEXT,
|
|
-- entity_id benennt das betroffene Objekt.
|
|
entity_id UUID,
|
|
-- result ist das Ergebnis der Handlung.
|
|
result TEXT NOT NULL,
|
|
-- ip_address ist die Herkunft der Anfrage.
|
|
ip_address INET,
|
|
-- user_agent ist die Kennung des verwendeten Programms.
|
|
user_agent TEXT,
|
|
-- details trägt unbedenklichen Zusatzkontext. Niemals Secrets.
|
|
details JSONB,
|
|
-- correlation_id verknüpft das Ereignis mit den Logzeilen derselben Operation.
|
|
correlation_id UUID,
|
|
-- created_at ist der Zeitpunkt des Ereignisses in UTC.
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
|
|
CONSTRAINT audit_events_result_valid CHECK (result IN ('success', 'failure', 'denied'))
|
|
);
|
|
|
|
COMMENT ON TABLE audit_events IS 'Append-only Protokoll sicherheitsrelevanter Handlungen. Änderungen und Löschungen sind per Trigger unterbunden.';
|
|
COMMENT ON COLUMN audit_events.details IS 'Unbedenklicher Zusatzkontext. Enthält niemals Secrets.';
|
|
|
|
-- Auditrecherchen laufen fast immer über Zeitraum, Benutzer oder Aktion.
|
|
CREATE INDEX audit_events_created_at_idx ON audit_events (created_at DESC);
|
|
CREATE INDEX audit_events_user_idx ON audit_events (user_id, created_at DESC);
|
|
CREATE INDEX audit_events_action_idx ON audit_events (action, created_at DESC);
|
|
|
|
-- Das Auditprotokoll ist append-only.
|
|
--
|
|
-- Die Regel wird in der Datenbank durchgesetzt und nicht allein in der Anwendung:
|
|
-- ein Angreifer mit Datenbankzugriff soll seine Spuren nicht durch ein einfaches
|
|
-- UPDATE oder DELETE verwischen können (PROMPT.md §40).
|
|
CREATE OR REPLACE FUNCTION reject_audit_modification() RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
RAISE EXCEPTION 'Auditereignisse duerfen nicht veraendert oder geloescht werden (append-only).';
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER audit_events_no_update
|
|
BEFORE UPDATE ON audit_events
|
|
FOR EACH ROW EXECUTE FUNCTION reject_audit_modification();
|
|
|
|
CREATE TRIGGER audit_events_no_delete
|
|
BEFORE DELETE ON audit_events
|
|
FOR EACH ROW EXECUTE FUNCTION reject_audit_modification();
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Berechtigungen (Stammdaten)
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
INSERT INTO permissions (name, description) VALUES
|
|
('users.read', 'Benutzer und deren Rollen einsehen'),
|
|
('users.write', 'Benutzer anlegen, ändern und löschen'),
|
|
('roles.read', 'Rollen und Berechtigungen einsehen'),
|
|
('roles.write', 'Rollen anlegen, ändern und löschen'),
|
|
('jobs.read', 'Backup-Jobs und deren Läufe einsehen'),
|
|
('jobs.write', 'Backup-Jobs anlegen, ändern und löschen'),
|
|
('jobs.run', 'Backup-Jobs sofort starten, pausieren und fortsetzen'),
|
|
('backups.read', 'Backups und Wiederherstellungspunkte einsehen'),
|
|
('restores.read', 'Wiederherstellungsvorgänge einsehen'),
|
|
('restores.execute', 'Wiederherstellungen durchführen'),
|
|
('repositories.read', 'Repositories und deren Zustand einsehen'),
|
|
('repositories.write', 'Repositories anlegen, ändern und prüfen'),
|
|
('agents.read', 'Agents und deren Zustand einsehen'),
|
|
('agents.write', 'Agents registrieren, sperren und Zugangsdaten wechseln'),
|
|
('providers.read', 'Virtualisierungsumgebungen einsehen'),
|
|
('providers.write', 'Virtualisierungsumgebungen verwalten'),
|
|
('verification.read', 'Verifikationsläufe und Ergebnisse einsehen'),
|
|
('verification.write', 'Verifikationen auslösen und abbrechen'),
|
|
('alerts.read', 'Meldungen und Ereignisse einsehen'),
|
|
('alerts.write', 'Meldungen bestätigen, auflösen und Regeln verwalten'),
|
|
('security.read', 'Sicherheitszustand und Befunde einsehen'),
|
|
('security.write', 'Sicherheitseinstellungen und Richtlinien ändern'),
|
|
('audit.read', 'Auditprotokoll einsehen'),
|
|
('reports.read', 'Berichte einsehen und erzeugen'),
|
|
('settings.read', 'Systemeinstellungen einsehen'),
|
|
('settings.write', 'Systemeinstellungen ändern'),
|
|
('monitoring.read', 'Zustand, Metriken und Statistiken einsehen');
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Rollen (Stammdaten laut PROMPT.md §42)
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
INSERT INTO roles (name, description, is_system) VALUES
|
|
('viewer', 'Nur lesender Zugriff auf den Systemzustand', TRUE),
|
|
('backup_operator', 'Verwaltet Backup-Jobs und deren Ausführung', TRUE),
|
|
('restore_operator', 'Führt Wiederherstellungen durch', TRUE),
|
|
('security_administrator', 'Verwaltet Sicherheitseinstellungen, Benutzer und Rollen', TRUE),
|
|
('infrastructure_administrator', 'Verwaltet Repositories, Agents und Virtualisierungsumgebungen', TRUE),
|
|
('auditor', 'Liest Auditprotokoll und Berichte', TRUE),
|
|
('super_administrator', 'Vollzugriff auf alle Funktionen', TRUE);
|
|
|
|
-- Viewer: ausschließlich lesend.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'viewer'
|
|
AND p.name IN ('jobs.read', 'backups.read', 'restores.read', 'repositories.read',
|
|
'agents.read', 'providers.read', 'verification.read', 'alerts.read',
|
|
'monitoring.read', 'reports.read');
|
|
|
|
-- Backup Operator: Jobs verwalten und starten.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'backup_operator'
|
|
AND p.name IN ('jobs.read', 'jobs.write', 'jobs.run', 'backups.read',
|
|
'repositories.read', 'agents.read', 'providers.read',
|
|
'verification.read', 'verification.write', 'alerts.read',
|
|
'monitoring.read', 'reports.read');
|
|
|
|
-- Restore Operator: Wiederherstellungen durchführen, aber keine Jobs ändern.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'restore_operator'
|
|
AND p.name IN ('backups.read', 'restores.read', 'restores.execute', 'jobs.read',
|
|
'repositories.read', 'agents.read', 'providers.read',
|
|
'verification.read', 'alerts.read', 'monitoring.read');
|
|
|
|
-- Security Administrator: Sicherheit, Benutzer und Rollen.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'security_administrator'
|
|
AND p.name IN ('users.read', 'users.write', 'roles.read', 'roles.write',
|
|
'security.read', 'security.write', 'audit.read', 'alerts.read',
|
|
'alerts.write', 'settings.read', 'monitoring.read');
|
|
|
|
-- Infrastructure Administrator: Repositories, Agents, Virtualisierung.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'infrastructure_administrator'
|
|
AND p.name IN ('repositories.read', 'repositories.write', 'agents.read', 'agents.write',
|
|
'providers.read', 'providers.write', 'jobs.read', 'backups.read',
|
|
'alerts.read', 'alerts.write', 'monitoring.read', 'settings.read',
|
|
'settings.write', 'verification.read');
|
|
|
|
-- Auditor: Protokoll und Berichte, ausdrücklich ohne Schreibrechte.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'auditor'
|
|
AND p.name IN ('audit.read', 'reports.read', 'security.read', 'users.read',
|
|
'roles.read', 'jobs.read', 'backups.read', 'restores.read',
|
|
'repositories.read', 'monitoring.read', 'alerts.read');
|
|
|
|
-- Super Administrator: alle Berechtigungen.
|
|
INSERT INTO role_permissions (role_id, permission_id)
|
|
SELECT r.id, p.id FROM roles r, permissions p
|
|
WHERE r.name = 'super_administrator';
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Nachtrag zu Migration 000001
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
-- system_settings konnte den Verweis auf den ändernden Benutzer erst erhalten,
|
|
-- nachdem die Benutzertabelle existiert (SYNCOVA_DATABASE.md §16).
|
|
ALTER TABLE system_settings
|
|
ADD COLUMN updated_by UUID REFERENCES users (id) ON DELETE SET NULL;
|
|
|
|
COMMENT ON COLUMN system_settings.updated_by IS 'Benutzer, der die Einstellung zuletzt geändert hat.';
|