diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..d21a36e --- /dev/null +++ b/TODO.md @@ -0,0 +1,138 @@ +# TODO-Liste + +## Offen +- [ ] 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). +- [ ] 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. +- [ ] 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. +- [ ] 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). +- [ ] 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. +- [ ] 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 1–3, verfügbare Ops-Ressourcen für Fingerprint-Freigaben und Sicherheitstests. +- [ ] 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). +- [ ] Keine; Onboarding-Policy (Strict Ops-First) und Sicherheitsvorgaben abgestimmt. +- [ ] HTTP-Basic wird extern via .htpasswd gepflegt; Webserver setzt Auth und ggf. REMOTE_USER. +- [ ] Die Applikation verifiziert keine internen Benutzer, erwartet ggf. REMOTE_USER zur Audit-Zuordnung. +- [ ] Beschreibung: Simple Health-Check. +- [ ] Antwort: 200 OK. +- [ ] Beschreibung: Liste aller hochgeladenen Playbooks (Metadaten). +- [ ] Query: ?limit=&offset=. +- [ ] Antwort: JSON Array [{id,name,filename,uploaded_by,uploaded_at}]. +- [ ] 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. +- [ ] Beschreibung: Metadaten zu einem Playbook. +- [ ] Antwort: JSON. +- [ ] 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}. +- [ ] Beschreibung: Statusabfrage (queued,running,success,failed). +- [ ] Antwort: JSON {run_id,status,exit_code,started_at,finished_at}. +- [ ] Beschreibung: Holt vollständiges stdout/stderr des Runs (Text/stream). +- [ ] Antwort: text/plain (oder chunked). +- [ ] Beschreibung: Listet referenzierbare SSH-Keys (nur lesend). +- [ ] Antwort: JSON [{key_id,filename,description}]. +- [ ] Beschreibung: Zugriff auf Run-Logs / Audit-Einträge (keine sensiblen Daten). +- [ ] Antwort: JSON. +- [ ] Die Applikation führt keine Änderung an SSH-Keys oder .htpasswd durch. +- [ ] Alle schreibenden Betriebsaufgaben (Permissions, Key-Rollout, TLS) sind außerhalb des MVP-Scopes. +- [ ] Auth via vorhandene HTTP-Basic/.htpasswd-Integration; Webserver stellt REMOTE_USER zur Verfügung. +- [ ] Ops-spezifische Endpoints (z. B. Approve) erfordern REMOTE_USER ∈ Ops-Gruppe (Ops-Policy). +- [ ] Transport: Produktion erfordert TLS (Ops-Deployment-Voraussetzung). +- [ ] 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. +- [ ] Zweck: Erstellt eine Onboarding-Anfrage / startet ein Onboarding-Job (sofern Pre-Checks erfolgreich sind). +- [ ] Auth: REMOTE_USER (any authenticated user). +- [ ] Konsumiert: application/json. +- [ ] Payload: { "host": "192.0.2.10", "port": 22, "login_user": "ubuntu", "login_password": "secret", "desired_user": "ansible", "generate_key": true, "public_key": null, "description": "Kurzinfo", "options": { "force_approve": false } }. +- [ ] Verhalten: +- [ ] Validierung von Pflichtfeldern. +- [ ] Erzeugt Onboard-Request und Onboard-Job, 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 (Rate-Limit pro User/Host). +- [ ] Zweck: Listet Onboarding-Requests (nur Metadaten). +- [ ] Query: ?limit=&offset=&status=. +- [ ] Antwort: JSON Array [{job_id, host, requested_by, status, created_at, fingerprint_sha256?}]. +- [ ] 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äts-gefiltert)" }. +- [ ] Zweck: Ops-Endpoint zur Freigabe eines abweichenden Host-Fingerprints. +- [ ] Auth: REMOTE_USER muss Ops sein (Server-Side check). +- [ ] Payload: { "approve": true, "operator_note": "Fingerprint validiert via call", "operator_id": "ops-username" }. +- [ ] Verhalten: Wenn genehmigt, Job wird zur Fortsetzung freigegeben; Audit-Eintrag mit operator_id erzeugt. +- [ ] Antwort: 200 OK { "job_id": "...", "status": "approved" }. +- [ ] Fehler: 403 Forbidden (wenn nicht Ops), 404 Not Found. +- [ ] Zweck: Bricht laufenden/queued Onboarding-Job ab (z. B. User Abbruch). +- [ ] Auth: Requester oder Ops. +- [ ] Antwort: 200 OK { "job_id": "...", "status": "cancelled" }. +- [ ] Zweck: Admin/Operator Sicht auf Onboard-Jobs (Metadaten). +- [ ] Filters: status, requested_by, host. +- [ ] Antwort: Array von job-Metadaten (keine sensitiven Inhalte). +- [ ] Zweck: Listet erzeugte Public-Keys (Metadaten only). +- [ ] Antwort: [{ "key_id": "...", "host_id": "...", "public_key_fingerprint": "...", "created_at": "..." }]. +- [ ] Zweck: Liefert redigierte Logs des Onboarding-Jobs (Ausgaben, Schritte). +- [ ] Sicherheits-Hinweis: Logs sind gesäubert; keine Passwörter oder private Key-Material enthalten. +- [ ] Antwort: text/plain oder JSON { "lines":[ ... ] }. +- [ ] Login-Password darf niemals geloggt werden; im API-Server mittelbar nur in-memory übergeben. +- [ ] API darf niemals privaten Schlüssel in Responses zurückliefern. +- [ ] Alle Endpoints, die sensible Ablaufsteuerung erlauben (approve, cancel), müssen REMOTE_USER-Checks durchführen. +- [ ] Rate-Limits: Schutz gegen bruteforce / DOS. +- [ ] Input-Sanitization: host/username dürfen keine Shell-Injection ermöglichen; SSH-Interaktionen erfolgen kontrolliert. +- [ ] Audit: Jeder state-wechsel (created, awaiting_approval, approved, onboarded, failed, cancelled) schreibt ein Metadaten-Audit (siehe [`webapp/entwicklung/schema.sql`](webapp/entwicklung/schema.sql:1) Anpassungen). +- [ ] UI-Form "Host Onboarding" ↟ POST /onboard/requests. +- [ ] UI-Ops Dashboard ↟ GET /onboard/requests?status=awaiting_approval. +- [ ] UI-Ops Approve Button ↟ POST /onboard/requests/{id}/approve. +- [ ] UI-User Status Polling ↟ GET /onboard/requests/{id}/status. +- [ ] UI-Logs ↟ GET /onboard/requests/{id}/logs. +- [ ] Schritt 1: User sendet POST /onboard/requests mit login_password. +- [ ] Schritt 2: API antwortet job_id. +- [ ] Schritt 3: Onboarding Service führt Pre-Check aus; bei Fingerprint-Mismatch → awaiting_approval. +- [ ] Schritt 4: Ops Approver ruft POST /onboard/requests/{id}/approve → Service fährt fort. +- [ ] Schritt 5: Job schreibt audit_logs und setzt Host Status auf onboarded oder failed. +- [ ] 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). + +## Erledigt +*(noch keine Einträge)* \ No newline at end of file