This commit is contained in:
2025-11-13 11:52:09 +01:00
parent a0eac46de2
commit bfd19299ab
6 changed files with 586 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
# API Endpoints — WebUI für AnsibleTUI
Hinweis zur Authentifizierung
- HTTPBasic wird extern via .htpasswd gepflegt; Webserver setzt Auth und ggf. REMOTE_USER.
- Die Applikation verifiziert keine internen Benutzer, erwartet ggf. REMOTE_USER zur AuditZuordnung.
Endpunkte (MVP)
GET /health
- Beschreibung: Simple HealthCheck
- Antwort: 200 OK
GET /playbooks
- Beschreibung: Liste aller hochgeladenen Playbooks (Metadaten)
- Query: ?limit=&offset=
- Antwort: JSON Array [{id,name,filename,uploaded_by,uploaded_at}]
POST /uploads
- Beschreibung: Upload eines ZIP/TAR mit Playbook(s)
- Konsumiert: multipart/form-data file=...
- Validierung: MIME und Dateiendung (zip,tar,tgz), Größenlimit
- Antwort: 201 Created + Metadaten
GET /playbooks/{id}
- Beschreibung: Metadaten zu einem Playbook
- Antwort: JSON
POST /playbooks/{id}/run
- Beschreibung: Startet einen Run via systemweiter ansible-playbook CLI. Keine Nutzung von ansible-runner.
- Body: optional JSON {inventory: string, extra_vars: object, tags: [string], become: bool}
- Behaviour: Prozess wird vom Service gestartet; stdout/stderr werden in temporäre Dateien geschrieben.
- Antwort: 202 Accepted {run_id}
GET /runs/{run_id}/status
- Beschreibung: Statusabfrage (queued,running,success,failed)
- Antwort: JSON {run_id,status,exit_code,started_at,finished_at}
GET /runs/{run_id}/output
- Beschreibung: Holt vollständiges stdout/stderr des Runs (Text/stream)
- Antwort: text/plain (oder chunked)
GET /keys
- Beschreibung: Listet referenzierbare SSHKeys (nur lesend)
- Antwort: JSON [{key_id,filename,description}]
GET /logs?limit=&offset=
- Beschreibung: Zugriff auf RunLogs / AuditEinträge (keine sensiblen Daten)
- Antwort: JSON
SicherheitsHinweis
- Die Applikation führt keine Änderung an SSHKeys oder .htpasswd durch.
- Alle schreibenden Betriebsaufgaben (Permissions, KeyRollout, TLS) sind außerhalb des MVPScopes.
## Erweiterung: Onboarding API — Endpoints für automatisches HostOnboarding
Authentifizierung / Autorisierung
- Auth via vorhandene HTTPBasic/.htpasswdIntegration; Webserver stellt REMOTE_USER zur Verfügung.
- Opsspezifische Endpoints (z. B. Approve) erfordern REMOTE_USER ∈ OpsGruppe (OpsPolicy).
- Transport: Produktion erfordert TLS (OpsDeploymentVoraussetzung).
Zusätzliche Endpoints (Übersicht)
- POST /onboard/requests
- GET /onboard/requests
- GET /onboard/requests/{id}/status
- POST /onboard/requests/{id}/approve
- POST /onboard/requests/{id}/cancel
- GET /onboard/jobs
- GET /onboard/keys
- GET /onboard/requests/{id}/logs
POST /onboard/requests
- Zweck: Erstellt eine OnboardingAnfrage / startet ein OnboardingJob (sofern PreChecks erfolgreich sind).
- Auth: REMOTE_USER (any authenticated user)
- Konsumiert: application/json
- Payload:
{
"host": "192.0.2.10", // host oder IP
"port": 22, // optional, default 22
"login_user": "ubuntu", // Account zur initialen LoginPhase (sudofähig)
"login_password": "secret", // nur intransit; wird nicht persistiert
"desired_user": "ansible", // Benutzer, der angelegt/wenn nötig benutzt wird
"generate_key": true, // true => Server erzeugt Schlüsselpaar (Ed25519/RSA4096 fallback)
"public_key": null, // optional, wenn false und Nutzer eigenen Schlüssel liefert
"description": "Kurzinfo",
"options": { // optional: z. B. {"force_approve":false}
"force_approve": false
}
}
- Verhalten:
- Validierung von Pflichtfeldern.
- Erzeugt OnboardRequest und OnboardJob, reply enthält { "job_id": "...", "status": "created" }.
- Wenn Fingerprint nicht mit Ops known_hosts übereinstimmt, wird status = "awaiting_approval".
- Antwort: 201 Created
{
"job_id": "uuid",
"status": "created" | "awaiting_approval" | "queued"
}
- Fehlercodes:
- 400 Bad Request (Validierungsfehler)
- 401 Unauthorized
- 429 Too Many Requests (RateLimit pro User/Host)
GET /onboard/requests
- Zweck: Listet OnboardingRequests (nur Metadaten)
- Query: ?limit=&offset=&status=
- Antwort: JSON Array [{job_id, host, requested_by, status, created_at, fingerprint_sha256?}]
GET /onboard/requests/{id}/status
- Zweck: Statusabfrage für einen Request
- Antwort:
{
"job_id": "...",
"host": "...",
"status": "created|queued|running|awaiting_approval|approved|onboarded|failed|cancelled",
"retries": 0,
"started_at": "...",
"finished_at": "...",
"error_message": "kurze Fehlerdiagnose (sensitivitätsgefiltert)"
}
POST /onboard/requests/{id}/approve
- Zweck: OpsEndpoint zur Freigabe eines abweichenden HostFingerprints
- Auth: REMOTE_USER muss Ops sein (ServerSide check)
- Payload:
{
"approve": true,
"operator_note": "Fingerprint validiert via call",
"operator_id": "ops-username"
}
- Verhalten: Wenn genehmigt, Job wird zur Fortsetzung freigegeben; AuditEintrag mit operator_id erzeugt.
- Antwort: 200 OK { "job_id": "...", "status": "approved" }
- Fehler: 403 Forbidden (wenn nicht Ops), 404 Not Found
POST /onboard/requests/{id}/cancel
- Zweck: Bricht laufenden/queued OnboardingJob ab (z. B. User Abbruch)
- Auth: Requester oder Ops
- Antwort: 200 OK { "job_id": "...", "status": "cancelled" }
GET /onboard/jobs
- Zweck: Admin/Operator Sicht auf OnboardJobs (Metadaten)
- Filters: status, requested_by, host
- Antwort: Array von jobMetadaten (keine sensitiven Inhalte)
GET /onboard/keys
- Zweck: Listet erzeugte PublicKeys (Metadaten only)
- Antwort: [{ "key_id": "...", "host_id": "...", "public_key_fingerprint": "...", "created_at": "..." }]
GET /onboard/requests/{id}/logs
- Zweck: Liefert redigierte Logs des OnboardingJobs (Ausgaben, Schritte)
- SicherheitsHinweis: Logs sind gesäubert; keine Passwörter oder private KeyMaterial enthalten.
- Antwort: text/plain oder JSON { "lines":[ ... ] }
SicherheitsHinweise für APIDesign
- LoginPassword darf niemals geloggt werden; im APIServer mittelbar nur inmemory übergeben.
- API darf niemals privaten Schlüssel in Responses zurückliefern.
- Alle Endpoints, die sensible Ablaufsteuerung erlauben (approve, cancel), müssen REMOTE_USERChecks durchführen.
- RateLimits: Schutz gegen bruteforce / DOS.
- InputSanitization: host/username dürfen keine ShellInjection ermöglichen; SSHInteraktionen erfolgen kontrolliert.
- Audit: Jeder statewechsel (created, awaiting_approval, approved, onboarded, failed, cancelled) schreibt ein MetadatenAudit (siehe [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1) Anpassungen).
Mapping UI ↔ API
- UIForm "Host Onboarding" ↟ POST /onboard/requests
- UIOps Dashboard ↟ GET /onboard/requests?status=awaiting_approval
- UIOps Approve Button ↟ POST /onboard/requests/{id}/approve
- UIUser Status Polling ↟ GET /onboard/requests/{id}/status
- UILogs ↟ GET /onboard/requests/{id}/logs
BeispielFlow (Kurz)
1. User sendet POST /onboard/requests mit login_password.
2. API antwortet job_id.
3. Onboarding Service führt PreCheck aus; bei FingerprintMismatch → awaiting_approval.
4. Ops Approver ruft POST /onboard/requests/{id}/approve → Service fährt fort.
5. Job schreibt audit_logs und setzt Host Status auf onboarded oder failed.
Referenzen zur weiteren Anpassung
- Architektur: [`webapp/entwicklung/architektur.md`](webapp/entwicklung/architektur.md:1)
- DB Schema: [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1)
- Roadmap: [`webapp/entwicklung/roadmap.md`](webapp/entwicklung/roadmap.md:1)

149
entwicklung/architektur.md Normal file
View File

@@ -0,0 +1,149 @@
# Architektur — WebUI für AnsibleTUI
Kurzer Überblick
Dieses Dokument beschreibt die finale Architektur für das MVP WebUI gemäß dem gewählten Profil:
Minimal — extern gepflegte .htpasswd, direkte ansibleplaybookCLI, ZIP/TARUploads, SSHKeys nur abgelegt.
Authentifizierung
- Nur externe .htpasswd zur HTTPBasicAuthentifizierung.
- Die Applikation validiert Anfragen gegen die Webserverauth (keine DBSync, keine interne Benutzerverwaltung).
- Betrieb: Ops pflegt .htpasswd; die Applikation nimmt keine Änderungen an .htpasswd vor.
Executor
- Playbooks werden durch Aufruf der systemweiten ansibleplaybook CLI ausgeführt.
- Kein Einsatz von ansiblerunner oder eines persistenten HintergrundExecutors im MVP.
- Die Applikation erstellt bei Bedarf temporäre Arbeitsverzeichnisse, schreibt erforderliche Metadaten und ruft ansibleplaybook mit den passenden Parametern.
SSHKeyHandling
- SSHKeys werden als Dateien im Dateisystem abgelegt (Uploads oder durch Ops bereitgestellt).
- Die Applikation ändert keine Besitz oder Berechtigungsattribute; Berechtigungsmanagement liegt bei den Betriebsprozessen/Opsteam.
- Keys werden referenziert, aber nicht automatisch verteilt oder in externe Stores synchronisiert.
Netzwerk / Deployment
- Kein integrierter ReverseProxy oder TLS im MVP.
- Container/Service horcht direkt auf Port 8000 (HTTP).
- TLS, ReverseProxy oder Ingress werden von der ZielBetriebsumgebung bereitgestellt und in späteren Releases integriert.
Uploads / Artefakte
- Unterstützte Uploads: ZIP und TAR. Eingangsprüfung auf erlaubte Dateitypen und Größenlimits.
- Entpackung erfolgt in sicheren, temporären Verzeichnissen; keine automatische Ausführung von hochgeladenem Code außer kontrollierten AnsiblePlaybooks.
Persistenz / Datenbank
- Minimales MVP vermeidet eigene BenutzerDB. Falls Metadaten nötig sind, begrenzt auf leichtgewichtige lokale Speicherung (z. B. SQLite).
- Keine Speicherung sensitiver Geheimnisse in der ApplikationsDB; Secrets verbleiben unter OpsVerwaltung.
Sicherheitshinweise
- Ops ist verantwortlich für sichere Aufbewahrung und Rollout von .htpasswd und SSHKeys.
- Applikationslogs vermeiden sensitive Inhalte; PlaybookOutputs können ggf. redigiert werden.
Offene Fragen
- Keine offenen Fragen — alle Entscheidungen sind gemäß dem MinimalProfil finalisiert.
## Erweiterung: Automatisches HostOnboarding (FeatureSpec)
Zweck
- Erlaubt automatisches Onboarding neuer Zielhosts mit wählbaren Optionen:
1. ProHost SSHKey: serverseitig erzeugtes Schlüsselpaar (Ed25519, Fallback RSA4096).
2. Login per Username + temporärem Passwort (Sudofähiger Account) für initiale Berechtigungsaufgaben.
3. Passwort wird nur einmalig verwendet und danach unverzüglich verworfen.
Kontext / Referenzen
- Diese Erweiterung baut auf bestehender Architektur auf; siehe Hauptdokumentation und APIListe: [`webapp/entwicklung/api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1), DBSchema: [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1) und Roadmap: [`webapp/entwicklung/roadmap.md`](webapp/entwicklung/roadmap.md:1).
DesignPrinzipien (Policy: Strict OpsFirst)
- Schlüssel: Ed25519 wird erzeugt. Falls Client/Host Ed25519 nicht unterstützt, Fallback RSA4096.
- HostFingerprint: strikt — Fingerprint muss mit Ops' known_hosts übereinstimmen oder vorab durch Ops manuell freigegeben werden. Abweichende Fingerprints erzeugen eine OnboardingSperre (OpsReview).
- Privater Schlüssel: niemals persistent auf Datenträger; nur im RAM des OnboardingJobs verfügbar, nur für die Dauer des Jobs.
- Passwort: nur im RAM gehalten; nach erfolgreichem Onboarding sofort unwiederbringlich verworfen. Bei Fehlern sind maximal 3 unmittelbare Retries erlaubt, danach OpsIntervention.
- Audit: nur Metadaten (username, host, fingerprintSHA256, event=start|success|fail, timestamp, operator_id bei manueller Freigabe). Keine Passwörter oder PrivateKeyMaterial in Logs oder DB. AuditRetention: 365 Tage.
Komponenten (Erweiterung)
- Onboarding UI (neues Formular, siehe APIMapping).
- Onboarding API (neue Endpoints; Auth via HTTPBasic/REMOTE_USER).
- Onboarding Service / Job Runner (zuständig für Erzeugung Key, SSHVerbindung, sudoAufgaben, KeyCopy).
- Ops Approval Queue (falls HostFingerprint nicht bekannt).
- DB Erweiterungen (HostsTabelle, OnboardJobs, KeyReferenzen, ephemeral markers) — siehe vorgeschlagene SchemaÄnderungen in [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1).
- AuditSubsystem: schreibt streng limitierte Events in audit_logs mit Tagging.
Prozessablauf (HighLevel)
- UI: Benutzer öffnet "Host Onboarding" Formular und gibt ein: hostname/ip, ssh_port (optional), username (für initiales PasswortLogin), temporäres Passwort (nur wenn Option 2 gewählt), gewünschter ZielBenutzername (z. B. ansible user) und evtl. Beschreibung.
- API: POST /onboard/requests erzeugt OnboardRequest, validiert Felder, erstellt OnboardJob und antwortet mit job_id.
- PreChecks: Onboarding Service prüft Erreichbarkeit (TCP), prüft HostFingerprint gegen Ops known_hosts.
- Falls Fingerprint unbekannt/abweichend: Job wird in OpsApprovalQueue gestellt; API gibt status=awaiting_approval zurück.
- Falls Fingerprint OK: Fortsetzung.
- Key Generation: Service erzeugt temporäres Schlüsselpaar (Ed25519 oder RSA4096); privater Schlüssel bleibt nur inmemory.
- SSH Login: Service stellt SSHSitzung mit provided username+password auf. Die LoginPhase verwendet sichere inmemory Credentials; Zeitüberschreitung/Fehler führen zu Retry (max 3).
- Privilegien: Service führt via sudo (password prompted, onetime use) die notwendigen Befehle aus (Erstellen Zieluser, setfacl/chown, Erstellen ~/.ssh, Deploy public key).
- KeyCopy: öffentlicher Schlüssel wird in das target user's authorized_keys geschrieben; Dateirechte gesetzt.
- Verifizieren: Service versucht Login per SSHKey (key auth) und optional überprüft sudoAusführung ohne Passwort (wenn operator gewünscht).
- Abschluss: Bei Erfolg markiert Job als completed, privater Schlüssel wird verworfen, OnboardResult in DB/Audit geschrieben. Bei Fehlern: bis 3 Retries, danach markiert als failed und Ops benachrichtigt.
- Cleanup: temporäre Verzeichnisse/Handles werden gelöscht, keine sensible Persistenz.
Mermaid: Ablaufdiagramm (vereinfachte Darstellung)
```
graph TB
UI[User nutzt OnboardingFormular]
API[POST /onboard/requests]
JOB[Onboarding Service: Job erstellt]
PRECHK[PreChecks: TCP + Fingerprint vs Ops known_hosts]
APPROVE[Ops Approval Queue]
KEYGEN[KeyErzeugung: Ed25519 / RSA4096]
SSHLOGIN[SSH Login mit User+Passwort (RAM)]
SUDO[SudoAufgaben: create user, setup ~/.ssh, copy pubkey]
VERIFY[Verify key auth]
SUCCESS[Onboarding success -> Audit + DB]
FAIL[Onboarding failed -> Audit + Ops Benachrichtigung]
UI --> API --> JOB --> PRECHK
PRECHK -- match --> KEYGEN --> SSHLOGIN --> SUDO --> VERIFY --> SUCCESS
PRECHK -- mismatch --> APPROVE --> JOB
VERIFY -- ok --> SUCCESS
VERIFY -- nok --> FAIL
```
Schnittstellen / Integration (Kurz)
- Neue API Endpoints (voll spezifiziert in [`webapp/entwicklung/api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1)):
- POST /onboard/requests — erstellt OnboardingRequest, Payload enthält host, port, username, password (nur intransit), desired_user, options (generate_key: true/false), description.
- GET /onboard/requests/{id}/status — Jobstatus, ops approval indicator.
- POST /onboard/requests/{id}/approve — Ops endpoint zum Freigeben eines Fingerprints (Auth: REMOTE_USER muss Ops sein).
- GET /onboard/keys — listet public keys erzeugt (readonly metadata).
- GET /onboard/jobs — Liste der Onboarding Jobs (nur Metadaten).
- Sicherheit: Passwords ONLY accepted via HTTPS (Ops deployment requirement). App muss niemals persistieren Passwörter; API akzeptiert Passwort im Request Body, Job Runner liest ihn und löscht danach.
DBÄnderungen (high level; detail in schema.sql)
- Neue Tabelle hosts:
- id, hostname/ip, primary_key_id (FK), fingerprint_sha256, onboarded_at, onboarded_by, status (pending/awaiting_approval/onboarded/failed), created_at
- Neue Tabelle onboard_jobs:
- id, host_id, requested_by, desired_user, options_json, retries, status, started_at, finished_at, error_message
- ssh_keys erweitert / referenziert (public key metadata only; private key never stored)
- audit_logs Nutzung: nur Metadaten (wie oben)
Sicherheits und AuditAspekte (Details)
- PasswortHandling:
- Password im APIRequest wird unmittelbar dem Job übergeben und nur im RAM gehalten.
- Nach Jobabschluss oder nach Fehlern/Timeouts wird der Speicher unverzüglich ohne Swap/Logging freigegeben.
- Implementationshinweis: nutze sichere SpeicherAPIs (mmap mit mlock wenn möglich) oder HostMechanismen, um Swapping zu verhindern.
- Private Key Handling:
- Erzeugung im JobProzess oder in isolierter Secure Enclave; privater Key nie auf Disk.
- Wenn OpsReview/Transfer erforderlich, Key kann kurzfristig (maximal JobDauer) in verschlüsseltem ProzessSpeicher gehalten werden; standardmäßig verboten.
- Fingerprint Handling:
- Vergleich gegen Ops known_hosts (Ops liefert Pfad oder API für known_hostsHash).
- Bei Mismatch: keine automatische Akzeptanz; OpsApproval erforderlich.
- Auditing:
- Erfasste Felder: event_type, job_id, host, fingerprint_sha256, requested_by, operator_id (bei approval), short status message, timestamp.
- Keine Speicherung sensibler Inhalte (kein Passwort, kein privater Key).
- AuditRetention: 365 Tage; älterer Einträge werden anonymisiert oder gelöscht gemäß OpsPolicy.
- LogSanitization:
- Playbook/SSH Outputs werden auf sensitive Patterns geprüft/redigiert bevor sie persistiert oder angezeigt werden.
Betriebsverantwortung / OpsAufgaben
- Ops liefert trusted known_hosts repository oder APIEndpoint zur FingerprintPrüfung.
- Ops sorgt für TransportTLS und sichere DeploymentKonfiguration (no plaintext HTTP in Prod).
- Ops prüft und genehmigt HostFingerprints in ApprovalQueue.
- Ops führt periodische Reviews/KeyRotation durch (nicht automatisch durch App).
Nächste Schritte (Dokumentation)
- APISpecs aktualisieren: [`webapp/entwicklung/api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1)
- SchemaÄnderungen in: [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1)
- Roadmap: neue Phase "Onboarding" mit Aufwandsschätzung und Meilensteine: [`webapp/entwicklung/roadmap.md`](webapp/entwicklung/roadmap.md:1)
(Ende Erweiterung)

57
entwicklung/roadmap.md Normal file
View File

@@ -0,0 +1,57 @@
# Roadmap — Web-UI für Ansible-TUI (Minimal-Profil)
## Überblick
- Ziel: Bereitstellung einer schlanken Web-UI, die Ansible-Playbooks per CLI startet.
- Authentifizierung erfolgt ausschließlich via extern gepflegter .htpasswd.
- SSH-Keys werden nur abgelegt und referenziert; Berechtigungen bleiben bei Ops.
- Keine Reverse-Proxy/TLS-Komponente im MVP; Service lauscht direkt auf Port 8000.
- Hochgeladene Artefakte: ZIP/TAR.
- Geplante Erweiterung: Automatisches Host-Onboarding (Strict Ops-First Policy) nach MVP-Release, abgestimmt mit [`webapp/entwicklung/architektur.md`](webapp/entwicklung/architektur.md:1) und [`webapp/entwicklung/api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1).
## Phase 0 Vorbereitung (Woche 1)
- Container-Basisimage finalisieren, Port 8000 exponieren.
- Ordnerstruktur für Uploads, temporäre Runs und SSH-Key-Ablage anlegen.
- Integration der Webserver-Basic-Auth (Übernahme REMOTE_USER, Fehlermeldungen).
- Dokumentation für Ops zur Pflege der .htpasswd erstellen.
## Phase 1 Implementierung Kernfunktionen (Woche 23)
- Datei-Uploads (ZIP/TAR) inkl. Validierung implementieren.
- Playbook-Metadaten persistieren laut [`schema.sql`](webapp/entwicklung/schema.sql:1).
- CLI-Executor: Wrapper für ansible-playbook inkl. Parameteraufbereitung.
- Run-Verwaltung (Status, Logpfade) bauen.
- Read-only-API zur SSH-Key-Liste implementieren.
- API-Endpunkte gemäß [`api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1) fertigstellen.
## Phase 2 Tests & Härtung (Woche 4)
- Funktionale Tests für Upload, Run-Start, Statuspolling.
- CLI-Aufruf unter verschiedenen Inventaren/Variablen validieren.
- Security-Checks: Keine Speicherung sensitiver Daten, Log-Redaktion.
- Belastungstest der Upload/Polling-Flows (einfacher Load-Test).
- Container-Image Review (kein TLS, nur HTTP).
## Phase 3 Release & Ops Handover (Woche 5)
- Build-/Release-Pipeline konfigurieren (Container Registry).
- Deployment-Checkliste erstellen (Port 8000, externe TLS-Schicht durch Ops).
- Monitoring-Anbindung (Basis: Health Endpoint, Log-Verfügbarkeit).
- Go-Live-Freigabe und Übergabe an Ops inkl. Betriebsdokumentation.
## Phase 4 Automatisches Host-Onboarding (Woche 69)
- Architektur- und Security-Review abschließen; Spezifikation finalisieren (Strict Ops-First Policy, siehe [`webapp/entwicklung/architektur.md`](webapp/entwicklung/architektur.md:1)).
- Datenbankmigrationen und Service-Layer implementieren (Hosts, Onboard-Jobs, Key-Metadaten) gemäß [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1).
- Backend: Onboarding-Service & Job-Runner (Key-Erzeugung, Fingerprint-Prüfung, sudo-Tasks) plus API-Endpunkte & Rate-Limits laut [`webapp/entwicklung/api_endpoints.md`](webapp/entwicklung/api_endpoints.md:1).
- UI/UX: Onboarding-Formular, Status-Detailansicht, Ops-Approval-Dashboard inkl. Log-Viewer.
- QA & Security: Integrationstests, Sudo-/SSH-Härtung, Pen-Test light, Memory-Handling-Checks (keine Persistenz von Passwort/Secret).
- Ops Enablement: Prozesse für known_hosts-Sync, Runbooks, Alerting, Eskalationspfade; Schulung der Ops-Gruppe.
- Staging-Dryrun mit realistischem Host; Post-Mortem + Go/No-Go Entscheidung.
- Abhängigkeiten: Abschluss Phase 13, verfügbare Ops-Ressourcen für Fingerprint-Freigaben und Sicherheitstests.
## Post-MVP Backlog
- Integrierter Reverse-Proxy/TLS-Termination.
- Erweiterter Credential-Store oder Secrets-Management.
- Rollenbasierte Zugriffssteuerung jenseits .htpasswd.
- UI-Verbesserungen für Run-Output (Streaming, Filter).
- Automatisierte Key-Rotation inklusive Berechtigungsupdates.
- Self-Service Ops Workflow für Re-Onboarding/Key-Rotation (Erweiterung der Onboarding-Plattform).
## Offene Fragen
- Keine; Onboarding-Policy (Strict Ops-First) und Sicherheitsvorgaben abgestimmt.

114
entwicklung/schema.sql Normal file
View File

@@ -0,0 +1,114 @@
-- Schema für minimale Metadatenhaltung (SQLite-kompatibel)
-- Profil: Minimal — externe .htpasswd, direkte ansible-playbook CLI, SSH-Keys nur abgelegt
-- Hinweis: Keine sensitiven Secrets oder Passwörter werden in dieser DB gespeichert.
-- Erweiterung: Automatisches Host-Onboarding (Strict Ops-First Policy)
PRAGMA foreign_keys = ON;
CREATE TABLE playbooks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
filename TEXT NOT NULL UNIQUE,
uploaded_by TEXT,
uploaded_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE runs (
id TEXT PRIMARY KEY,
playbook_id INTEGER NOT NULL,
inventory TEXT,
extra_vars_json TEXT, -- JSON-codierte Extra-Variablen
tags_json TEXT, -- JSON-codierte Tags
become INTEGER NOT NULL DEFAULT 0,
status TEXT NOT NULL, -- queued|running|success|failed
exit_code INTEGER,
started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
finished_at DATETIME,
stdout_path TEXT, -- Dateipfad zu stdout
stderr_path TEXT, -- Dateipfad zu stderr
FOREIGN KEY(playbook_id) REFERENCES playbooks(id) ON DELETE CASCADE
);
-- Host-Onboarding: Hosts und Jobs
CREATE TABLE hosts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
host_identifier TEXT NOT NULL UNIQUE, -- FQDN oder IP
port INTEGER NOT NULL DEFAULT 22,
fingerprint_sha256 TEXT, -- SHA256 des Host-Keys (nur Fingerprint)
fingerprint_status TEXT NOT NULL DEFAULT 'pending', -- pending|verified|mismatch
status TEXT NOT NULL DEFAULT 'pending', -- pending|awaiting_approval|onboarded|failed|cancelled
description TEXT,
requested_by TEXT,
approved_by TEXT,
approved_at DATETIME,
onboarded_at DATETIME,
last_error TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME
);
CREATE TABLE onboard_jobs (
id TEXT PRIMARY KEY, -- UUID
host_id INTEGER NOT NULL,
requested_by TEXT NOT NULL,
login_user TEXT NOT NULL,
desired_user TEXT NOT NULL,
options_json TEXT, -- JSON-codierte Optionen/Flags
approval_required INTEGER NOT NULL DEFAULT 0,
approved_by TEXT,
approved_at DATETIME,
status TEXT NOT NULL, -- created|queued|running|awaiting_approval|approved|onboarded|failed|cancelled
retries INTEGER NOT NULL DEFAULT 0,
max_retries INTEGER NOT NULL DEFAULT 3,
started_at DATETIME,
finished_at DATETIME,
error_code TEXT,
error_message TEXT,
last_fingerprint_sha256 TEXT, -- Fingerprint zuletzt geprüft
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(host_id) REFERENCES hosts(id) ON DELETE CASCADE
);
CREATE TABLE ssh_keys (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key_id TEXT NOT NULL UNIQUE,
host_id INTEGER UNIQUE, -- Pro Host genau ein aktiver Key
key_type TEXT NOT NULL, -- ed25519|rsa4096|external
public_key TEXT, -- Öffentlicher Schlüssel (optional für extern verwaltete Keys)
fingerprint_sha256 TEXT NOT NULL UNIQUE,
managed_externally INTEGER NOT NULL DEFAULT 0, -- 0: App erzeugt/verwalten, 1: Ops verwaltet
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(host_id) REFERENCES hosts(id) ON DELETE CASCADE
);
CREATE TABLE audit_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
run_id TEXT,
onboard_job_id TEXT,
host_id INTEGER,
category TEXT NOT NULL,
message TEXT NOT NULL,
metadata_json TEXT, -- JSON-kodierte Zusatzinfos (z. B. Fingerprint-Hash)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY(run_id) REFERENCES runs(id) ON DELETE SET NULL,
FOREIGN KEY(onboard_job_id) REFERENCES onboard_jobs(id) ON DELETE SET NULL,
FOREIGN KEY(host_id) REFERENCES hosts(id) ON DELETE SET NULL
);
CREATE INDEX idx_runs_playbook ON runs(playbook_id);
CREATE INDEX idx_runs_status ON runs(status);
CREATE INDEX idx_hosts_status ON hosts(status);
CREATE INDEX idx_hosts_fingerprint_status ON hosts(fingerprint_status);
CREATE INDEX idx_onboard_jobs_host ON onboard_jobs(host_id);
CREATE INDEX idx_onboard_jobs_status ON onboard_jobs(status);
CREATE INDEX idx_ssh_keys_fingerprint ON ssh_keys(fingerprint_sha256);
CREATE INDEX idx_audit_logs_run ON audit_logs(run_id);
CREATE INDEX idx_audit_logs_job ON audit_logs(onboard_job_id);
CREATE INDEX idx_audit_logs_host ON audit_logs(host_id);
-- Alle Betriebsaufgaben (Pflege .htpasswd, TLS, SSH-Key Berechtigungen) liegen außerhalb der Applikation.
-- Onboarding-Policy: Privater Schlüssel und Passwörter werden nicht persistiert; nur Fingerprints und Metadaten.