syncova-backup/docs/api.md
Jerrit Fritzsche 610719c316
Some checks failed
CI / Backend (Go) (push) Failing after 3m7s
CI / Frontend (React/TypeScript) (push) Successful in 37s
CI / Sicherheitsprüfungen (push) Successful in 44s
Syncova Backups V1
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>
2026-08-17 09:10:54 +02:00

7.1 KiB

API

/api/v1 — eingefroren. Die vollständige Liste aller 102 Endpunkte samt geforderter Berechtigung steht maschinenlesbar in apps/api/internal/httpapi/contract_routes.txt; eine Prüfung schlägt an, sobald sich etwas daran ändert. Der verbindliche Vertrag ist SYNCOVA_API.md.

Dieses Dokument erklärt, wie die API sich verhält — die Dinge, die man aus einer Endpunktliste nicht abliest.

Die Antworthülle ist maßgeblich, nicht der HTTP-Status

{ "data": { "…": "…" }, "meta": { "request_id": "…" } }
{ "error": { "code": "BACKUP_REPOSITORY_UNAVAILABLE",
             "message": "…", "details": {}, "request_id": "…" } }

Werten Sie error gegen data aus, nicht response.ok. GET /health liefert bei kritischem Zustand 503 mit vollständigem data-Bericht: Monitoring schlägt an, und die Oberfläche kann trotzdem anzeigen, was kaputt ist. Ein Client, der bei 503 nur „Fehler" meldet, verschenkt genau die Auskunft, die er braucht.

Fehlercodes sind sprechende Konstanten in SCREAMING_SNAKE_CASE. Sie sind Teil des Vertrags; werten Sie sie aus, nicht den Meldungstext — der ist für Menschen und darf sich ändern.

request_id steht in jeder Antwort, auch der erfolgreichen. Bei einer Rückfrage ist sie das Einzige, womit sich eine Anfrage in den Protokollen wiederfinden lässt.

Anmeldung

curl -X POST https://<server>/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"…"}'
{ "data": { "mfa_required": false,
            "tokens": { "access_token": "…", "refresh_token": "…",
                        "access_expires_at": "…", "refresh_expires_at": "…" },
            "user": { "…": "…" } } }

Bei "mfa_required": true folgt POST /auth/mfa/verify mit dem Code.

Opake Tokens, keine JWT. Der Grund ist die sofortige Widerrufbarkeit: Ein JWT bliebe nach Sperre oder Passwortänderung bis zum Ablauf gültig. Gespeichert wird serverseitig nur der SHA-256-Hash.

Danach Authorization: Bearer <access_token>.

Zwei Pflichtfelder im Kopf

Kopfzeile Wann Wozu
X-Correlation-ID jede Anfrage verbindet Anfrage und Logzeilen. Nur eine gültige UUID wird übernommen, sonst verworfen — damit keine fremden Zeichenketten in die Protokolle geraten
Idempotency-Key siehe unten verhindert Doppelausführung

Idempotenz ist erforderlich bei: Auftrag anlegen, Backup starten, Wiederherstellung anlegen, Repository eintragen und destruktiven Konfigurationsänderungen. Ein wiederholter Aufruf mit demselben Schlüssel liefert das erste Ergebnis, statt ein zweites Mal zu handeln.

Berechtigungen

Jeder Endpunkt verlangt genau eine. Sie steht in der eingefrorenen Liste, weil eine stillschweigend gelockerte Prüfung die gefährlichste Änderung überhaupt wäre: Der Endpunkt funktioniert weiter, nur dürfen ihn plötzlich mehr Leute aufrufen.

Vier Sonderfälle:

  • - — ohne Anmeldung erreichbar: /health*, /auth/login, /auth/refresh, /auth/mfa/verify und /agents/register (ein sich aufnehmender Agent besitzt noch kein Betriebstoken).
  • sitzung — angemeldet, ohne besondere Berechtigung: /me, /auth/logout, MFA-Einrichtung für sich selbst.
  • agent-token — Betriebstoken eines Agenten statt Benutzersitzung.
  • restores.overwrite steckt nicht in restores.execute.

Berechtigungen im Frontend sind Anzeige, keine Sicherung. Sie verhindern Sackgassen; geprüft wird auf dem Server.

Seitenweise Ergebnisse

GET /api/v1/backups?page=2&page_size=50
{ "data": [ … ], "meta": { "page": 2, "page_size": 50, "total": 312,
                           "request_id": "…" } }

Dateien

Berichte kommen als CSV, JSON oder PDF — ohne Antworthülle. Der Fehlerfall dagegen trägt sie.

Prüfen Sie den Inhaltstyp, bevor Sie speichern. Sonst landet eine Fehlermeldung als bericht.pdf im Download-Ordner.

Die Endpunkte im Überblick

Bereich Endpunkte Wofür
/auth, /me 7 Anmeldung, Sitzung, eigener zweiter Faktor
/users, /roles, /permissions 12 Konten und Rollen
/repositories 11 Eintragen, Zustand, Prüfung, Integritätslauf, Katalogaufbau, Aufbewahrung
/jobs 8 Aufträge und deren Läufe
/backups 8 Wiederherstellungspunkte, Schutz, Legal Hold, Bewertung
/restores 6 Vorabprüfung, Ausführung, Fortsetzung
/verification 5 Prüfläufe bis zum Wiederherstellungstest
/agents 11 Aufnahme, Verwaltung, Auftragsabholung
/proxmox, /virtual-machines 10 Verbünde, Bestandsaufnahme, Gäste
/alerts, /notification-channels 8 Meldungen und Zustellung
/metrics, /reports, /security, /audit-events 7 Kennzahlen, Berichte, Sicherheitslage, Protokoll
/health 3 Betriebszustand

Vier Verhaltensweisen, die überraschen

POST /jobs/{id}/run antwortet 202, nicht 201. Der Lauf ist eingereiht; die Sicherung hat nicht begonnen. Ein zweiter Anstoß bei laufendem Auftrag ergibt 409, nicht 500.

POST /repositories legt nichts an, sondern übernimmt. Ein Repository entsteht auf einem Datenträger (syncova-repo create). Der Endpunkt öffnet das vorhandene, liest dessen Kennung aus dem Descriptor und trägt es ein. Liegt dort keines, wird abgelehnt — ein Eintrag ohne Ablage dahinter wäre ein Ziel, das erst um zwei Uhr nachts als nicht vorhanden auffällt.

Der Integritätslauf meldet einen Befund nicht als Fehler. POST /repositories/{id}/integrity-scan antwortet 200 mit "healthy": false. „Die Prüfung schlug fehl" und „das Repository ist beschädigt" sind zwei völlig verschiedene Lagen; sie zu verwechseln macht aus einem Befund einen Werkzeugfehler.

Kennzahlen unterscheiden „null" und „unbekannt". Jeder Punkt einer Zeitreihe trägt has_value. Ein Zeitfenster ohne Sicherungslauf hat keinen Durchsatz — nicht null Byte je Sekunde. Zeichnen Sie die Linie unterbrochen, nicht durch den Nullpunkt.

Was es nicht gibt

  • Kein WebSocket/SSE-Stream. /api/v1/events/stream ist im Vertrag vorgesehen und nicht umgesetzt. Live-Anzeigen laufen über Abfragen.
  • Keine Massenoperationen. Kein DELETE /backups?filter=… — destruktive Handlungen gehen einzeln und werden einzeln auditiert.
  • Kein PUT. Änderungen laufen über PATCH mit den Feldern, die sich tatsächlich ändern.

Fehlercodes, die man kennen sollte

Code Status Bedeutung
VALIDATION_FAILED 422 fachlich ungültig — die Meldung sagt, was fehlt
PERMISSION_DENIED 403 angemeldet, aber nicht berechtigt
CONFLICT 409 Zustand passt nicht: Auftrag läuft bereits, Name vergeben, Verbund in Benutzung
RATE_LIMITED 429 zu viele Anfragen (Vorgabe 600/min)
SERVICE_UNAVAILABLE 503 Abhängigkeit weg. Bei Datenbankausfall ausdrücklich nicht „Sitzung abgelaufen" — die Meldung sagt: „Das ist kein Problem Ihrer Sitzung."
NOT_IMPLEMENTED 501 geplant, aber nicht gebaut. Wird angezeigt statt vorgetäuscht