docs: overhaul repository documentation

This commit is contained in:
2026-01-15 08:54:52 +01:00
parent c41482a7b3
commit 10ec58f744
22 changed files with 575 additions and 108 deletions

59
docs/ARCHITECTURE.md Normal file
View File

@ -0,0 +1,59 @@
ID: DOC_000012 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Architektur
## Systemuebersicht
Safe Kiddo Daemon ist ein FastAPI-basierter Service, der lokale Systemkonten verwaltet. Er kombiniert:
- API und Web-UI (FastAPI + Jinja2 Templates)
- Authentifizierung (PAM und optional OIDC)
- Systemaktionen via sudo/usermod/pkill/shutdown
- Update-Client-Integration (externes Update-Service-Backend)
## Module und Verantwortlichkeiten
- `backend/app.py`: API-Routing, Web-UI-Endpunkte, Update-Endpunkte.
- `backend/auth.py`: PAM-Login, JWT-Handling, Auth-Guards, Allowlists.
- `backend/oidc.py`: OIDC Discovery, Token-Exchange, JWT-Validierung.
- `backend/actions.py`: Systemaktionen (lock/unlock, notify, sound, shutdown).
- `backend/update.py`: Update-Enrollment, Manifest-Check, Update/Rollback-Start, Status/Logs.
- `backend/settings.py`: Zentrale ENV-Konfiguration.
- `backend/templates/` + `backend/static/`: Web-UI.
- `scripts/*.sh`: Installation, Deployment, Update-Client, Rollback, OIDC-Registration.
## Daten- und Kontrollfluss
### Login und Auth
1. `POST /login` authentifiziert via PAM.
2. JWT wird erstellt und als Cookie oder Bearer-Token genutzt.
3. Schutz aller Admin-Endpunkte via `get_current_admin`.
### OIDC-Flow (optional)
1. `GET /login/oidc/start` generiert State und leitet zum IdP.
2. Callback `GET /login/oidc/callback` validiert State, tauscht Code gegen ID-Token.
3. ID-Token wird gegen JWKS geprueft, Username extrahiert, Session gesetzt.
### Benutzeraktionen
1. `POST /users/{username}/disable` ruft `actions.disable_user`.
2. Systemaktionen: `usermod -L`, optional notify/sound, `pkill`, optional `shutdown`.
3. `POST /users/{username}/enable` fuehrt `usermod -U` aus.
### Update-Flow
1. `POST /update/enroll` schreibt Langzeit-Token in `SKD_UPDATE_TOKEN_FILE`.
2. `POST /update/check` ruft Manifest beim Update-Service ab.
3. `POST /update/apply` startet `scripts/update_client.sh` asynchron.
4. `POST /update/rollback` startet `scripts/rollback_client.sh` asynchron.
5. Status/Logs werden lokal in Dateien geschrieben und optional an den Update-Service gemeldet.
## Designentscheidungen und Tradeoffs
- **Root-Run**: Service laeuft als root, da PAM und Systemkommandos Root erfordern.
- **JWT + Cookie**: Einfache lokale Auth; keine externe Session-Datenbank.
- **OIDC optional**: OIDC ist optional, PAM bleibt als Fallback aktiv.
- **Update als Script**: Update/Backup/Swap via Bash-Skripte fuer einfache Ops, Tradeoff: weniger granularer Fehler-Handling.
## Erweiterungspunkte
- **Auth**: Weitere Auth-Mechanismen koennen in `backend/auth.py` integriert werden.
- **UI**: Templates unter `backend/templates/` und CSS in `backend/static/`.
- **Update-Client**: Anpassung der Update-Strategie in `scripts/update_client.sh`.
- **Notifications/Sound**: Konfigurierbar per `SKD_NOTIFY_SEND_PATH`, `SKD_SOUND_PLAYER`, `SKD_SOUND_FILE`.
## Spezifikationen
- Update-Service OpenAPI: `docs/architecture/openapi.yaml` und `docs/architecture/openapi/`.

54
docs/CONFIGURATION.md Normal file
View File

@ -0,0 +1,54 @@
ID: DOC_000011 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Konfiguration
## Speicherort
Die Konfiguration erfolgt per ENV-Datei, standardmaessig `/etc/skd/env`. Vorlage: `env.example`.
## Authentifizierung
- `SKD_AUTH_MODE` (default `pam`): `pam` oder `oidc`. Ungueltige Werte fallen auf `pam` zurueck. Hinweis: Der Wert wird aktuell nicht zur Erzwingung genutzt; OIDC ist aktiv, sobald die OIDC-Variablen gesetzt sind.
- `SKD_AUTH_SECRET` (default `change-me-secret`): HMAC-Secret fuer JWTs.
- `SKD_TOKEN_TTL_SECONDS` (default `900`): Token-Laufzeit in Sekunden.
- `SKD_AUTH_ALLOWED_USERS` (default leer): Kommagetrennte Liste erlaubter Admin-User (gilt fuer PAM und OIDC).
- `SKD_AUTH_ALLOWED_GROUPS` (default `sudo`): Erlaubte Gruppen fuer PAM-Login.
- `SKD_AUTH_PAM_SERVICE` (default `login`, auf Debian/Ubuntu via `install.sh` auf `skd` gesetzt).
## OIDC
OIDC ist optional und zusaetzlich zu PAM.
- `SKD_OIDC_ISSUER`
- `SKD_OIDC_CLIENT_ID`
- `SKD_OIDC_CLIENT_SECRET`
- `SKD_OIDC_REDIRECT_URI` (default `http://localhost:8000/login/oidc/callback`)
- `SKD_OIDC_SCOPES` (default `openid profile email`)
- `SKD_SESSION_COOKIE_SECURE` (default `false`): Setze `true` fuer HTTPS.
- `SKD_OIDC_STATE_COOKIE_NAME` (default `skd_oidc_state`)
## Session/Benutzerverwaltung
- `SKD_SESSION_COOKIE_NAME` (default `skd_session`)
- `SKD_ALLOWED_USERS` (default leer): Optionales Allowlist fuer verwaltbare System-User.
## Aktionen (Countdown/Notify/Sound)
- `SKD_DEFAULT_COUNTDOWN` (default `60` Sekunden)
- `SKD_DEFAULT_SOUND` (default `false`)
- `SKD_NOTIFY_TIMEOUT` (default `5` Sekunden)
- `SKD_NOTIFY_SEND_PATH` (default `notify-send`)
- `SKD_SOUND_PLAYER` (default `paplay`)
- `SKD_SOUND_FILE` (default `/usr/share/sounds/freedesktop/stereo/dialog-warning.oga`)
## Update-Client
- `SKD_UPDATE_SERVICE_URL` (default `https://update.wlkns.org`)
- `SKD_UPDATE_PROJECT_ID` (default `safe-kiddo-control`)
- `SKD_UPDATE_ENROLL_TOKEN` (optional; fuer `/update/enroll`)
- `SKD_UPDATE_TOKEN` (optional; alternativ per Datei)
- `SKD_UPDATE_TOKEN_FILE` (default `/var/lib/skd/update_token`)
- `SKD_UPDATE_STATUS_FILE` (default `/var/lib/skd/update_status.json`)
- `SKD_UPDATE_LOG_FILE` (default `/var/lib/skd/update_logs.jsonl`)
- `SKD_UPDATE_INTERVAL` (default `3600`): Hinweis: wird aktuell nur eingelesen, aber nicht automatisch genutzt.
## Dry-Run
- `SKD_DRY_RUN` (default `false`): Keine echten System-Aktionen, nur Logging.
## Hinweise
- `scripts/install.sh` erstellt `/etc/skd/env` und setzt Default-Werte fuer PAM/Allowed-User.
- Aenderungen in `/etc/skd/env` erfordern einen Service-Restart (`sudo systemctl restart skd.service`).

68
docs/DEPLOYMENT.md Normal file
View File

@ -0,0 +1,68 @@
ID: DOC_000014 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Deployment
## Lokale Installation (systemd)
`./scripts/install.sh` fuehrt folgende Schritte aus:
- legt Service-User/Group an
- kopiert das Projekt nach `/opt/sk`
- erstellt/aktualisiert `.venv`
- erstellt `/etc/skd/env` aus `env.example`
- schreibt eine systemd-Unit nach `/etc/systemd/system/skd.service`
Beispiel:
```bash
sudo ./scripts/install.sh
sudo systemctl status skd.service
```
## Manuelles Starten
```bash
./scripts/run.sh
```
## Remote-Deploy (SSH)
`./scripts/deploy.sh` packt das Repo und deployt es auf einen Zielhost.
Konfiguration in `deploy_hosts.yml`.
Beispiel:
```bash
./scripts/deploy.sh kid-laptop
```
## Deployment via ZIP
Im Repo liegt `sk_deploy.zip`. Dieses Archiv kann auf den Zielhost kopiert und nach `/opt/sk` entpackt werden.
Anschliessend Abhaengigkeiten installieren und Service neu starten:
```bash
sudo -u skd /opt/sk/.venv/bin/pip install -r /opt/sk/backend/requirements.txt
sudo systemctl restart skd.service
```
## Update des Services
`./scripts/update.sh` zieht den Branch neu und fuehrt einen harten Reset aus.
Wichtig: Das Script nutzt `git reset --hard origin/main`.
```bash
sudo ./scripts/update.sh
```
## Update-Client (Remote Update Service)
Die Update-API startet `scripts/update_client.sh` bzw. `scripts/rollback_client.sh`.
Wichtige ENV-Variablen:
- `SKD_UPDATE_SERVICE_URL`
- `SKD_UPDATE_PROJECT_ID`
- `SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE`
Voraussetzungen auf dem Host:
- `curl`, `tar`, `sha256sum`, `python3`, `systemctl`
Enrollment-Tools:
- `scripts/manual_enroll.py`: Enrollment direkt gegen den Update-Service, schreibt Token in `SKD_UPDATE_TOKEN_FILE`.
- `scripts/enroll_local.py`: Enrollment ueber die lokale API (`/update/enroll`), benoetigt Admin-Session; `--token` setzen (Default-Token ist nur Prototyp-Altlast).
Lokale Status/Logs:
- `SKD_UPDATE_STATUS_FILE` (default `/var/lib/skd/update_status.json`)
- `SKD_UPDATE_LOG_FILE` (default `/var/lib/skd/update_logs.jsonl`)
## Backup/Restore
- Bei Apply wird `/opt/sk` nach `/opt/sk_backup_1.2.3_1700000000` verschoben (Beispiel).
- Rollback nutzt das letzte Backup (`/opt/sk_backup_*`).

44
docs/DEVELOPMENT.md Normal file
View File

@ -0,0 +1,44 @@
ID: DOC_000013 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Development
## Repository-Struktur (Kurz)
- `backend/`: FastAPI-App, Auth, Update-Logik, Templates, Static Assets.
- `scripts/`: Install/Deploy/Update/Helper-Skripte.
- `systemd/`: Beispiel-Unit.
- `docs/architecture/`: OpenAPI-Spezifikation fuer Update-Service.
- `docs/`: Dokumentation.
- `assets/`: Branding und Design.
- `sk.sh`: Legacy-CLI.
## Lokales Setup
```bash
./scripts/create_venv.sh
source .venv/bin/activate
./scripts/run.sh
```
Standard: `0.0.0.0:80`. Fuer andere Ports:
```bash
HOST=127.0.0.1 PORT=8000 ./scripts/run.sh
```
## Tests und Lint
Im Repo sind keine automatisierten Tests enthalten. Verfuegbare Checks:
- Bash-Syntax: `bash -n sk.sh`
- ShellCheck: `shellcheck sk.sh`
## Coding Conventions
- Bash 4+, `set -euo pipefail` in neuen Skripten.
- Python: FastAPI-Patterns, klare Modultrennung (Auth, Actions, Update, OIDC).
## Beitrag und Workflow
- Arbeite mit Feature-Branches.
- Aktualisiere `VERSION`, Doku-Header und `CHANGELOG.md` gemaess SOP.
- PRs sollten Verhalten, Risiken und manuelle Tests beschreiben.
## CI/CD
Aktuell keine CI/CD-Pipeline im Repository definiert.
## Legacy/Interna
- `SKD_UPDATE_URL` und `SKD_UPDATE_STATUS_URL` sind in `backend/settings.py` noch vorhanden, werden aber im aktuellen Code nicht genutzt.

21
docs/FAQ.md Normal file
View File

@ -0,0 +1,21 @@
ID: DOC_000015 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# FAQ
## Braucht der Dienst Root-Rechte?
Ja. PAM-Authentifizierung und Systemkommandos (usermod/pkill/shutdown) erfordern Root.
## Kann ich OIDC ohne PAM nutzen?
OIDC ist optional und zusaetzlich zu PAM. PAM bleibt als Fallback aktiv.
## Wie aendere ich den Port?
- Lokaler Run: `PORT=8000 ./scripts/run.sh`
- Systemd: Unit-Datei in `/etc/systemd/system/skd.service` anpassen und Service neu starten.
## Gibt es einen Docker-Container?
Nein, im Repository ist kein Docker-Setup enthalten.
## Wo liegen Logs?
- systemd: `journalctl -u skd.service`
- Update-Status/Logs: siehe `SKD_UPDATE_STATUS_FILE` und `SKD_UPDATE_LOG_FILE`.

48
docs/GETTING_STARTED.md Normal file
View File

@ -0,0 +1,48 @@
ID: DOC_000009 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Getting Started
## Ziel
Schneller Einstieg fuer neue Nutzer: Installation, erster Login und erste Aktion.
## Voraussetzungen
- Linux-System mit systemd.
- Root-Zugriff (PAM, usermod, shutdown).
- Python 3, curl, tar, sha256sum (fuer Update-Client-Skripte).
- Optional: notify-send (Benachrichtigungen), paplay/aplay (Sound).
## Schnellstart
```bash
# 1) Repo installieren
sudo mkdir -p /opt/sk
sudo git clone ssh://git@git.wlkns.org:2222/stephan/kiddo /opt/sk
# Hinweis: verwende hier die Repo-URL deiner Instanz
cd /opt/sk
# 2) Installation (legt Service-User, env, systemd-Unit an)
./scripts/install.sh
# 3) Service pruefen
sudo systemctl status skd.service
# 4) Login (PAM)
curl -s -X POST -H "Content-Type: application/json" \
-d '{"username":"root","password":"..."}' \
http://localhost/login
```
## Erster API-Test
```bash
token=$(curl -s -X POST -H "Content-Type: application/json" \
-d '{"username":"root","password":"example-password"}' \
http://localhost/login | jq -r .token)
curl -s -H "Authorization: Bearer $token" http://localhost/me
```
Hinweis: `jq` ist optional; ohne jq das Token manuell aus der JSON-Antwort lesen.
## Naechste Schritte
- Konfiguration anpassen: `docs/CONFIGURATION.md`
- API und Web-UI nutzen: `docs/USAGE.md`
- Deployment und Updates: `docs/DEPLOYMENT.md`

37
docs/TROUBLESHOOTING.md Normal file
View File

@ -0,0 +1,37 @@
ID: DOC_000016 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Troubleshooting
## Service startet nicht
- Status pruefen: `sudo systemctl status skd.service`
- Logs: `sudo journalctl -u skd.service -n 200 --no-pager`
- Port 80 belegt? Test: `sudo ss -ltnp | grep ':80'`
## 401/403 bei API-Aufrufen
- Bearer-Token fehlt oder abgelaufen.
- Nutzer nicht in `SKD_AUTH_ALLOWED_USERS` oder `SKD_AUTH_ALLOWED_GROUPS`.
- `SKD_AUTH_SECRET` geaendert? Tokens muessen neu erzeugt werden.
## OIDC-Login fehlschlaegt
- `SKD_OIDC_ISSUER`, `SKD_OIDC_CLIENT_ID`, `SKD_OIDC_CLIENT_SECRET` gesetzt?
- Redirect-URI exakt registriert?
- Netzwerkzugriff auf Discovery/JWKS moeglich?
## Benachrichtigung/Sound fehlt
- `notify-send` fehlt: `sudo apt install libnotify-bin`
- Sound-Player fehlt: `paplay` oder `aplay` installieren.
- `SKD_NOTIFY_SEND_PATH` oder `SKD_SOUND_PLAYER` falsch gesetzt.
## Update-Check meldet "Client is not enrolled"
- `SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE` fehlt.
- Enrollment ueber `/update/enroll` oder `scripts/manual_enroll.py` durchfuehren.
## Update-Apply fehlschlaegt
- Update-Service nicht erreichbar oder Token ungueltig.
- Prüfe `SKD_UPDATE_STATUS_FILE` und `SKD_UPDATE_LOG_FILE`.
- Hinweis: `update_client.sh` wird asynchron gestartet und stdout/stderr werden verworfen.
## Rollback meldet "no backup found"
- Es existiert kein `/opt/sk_backup_*` vom vorherigen Update.
- Rollback erst nach mindestens einem erfolgreichen Update moeglich.

80
docs/USAGE.md Normal file
View File

@ -0,0 +1,80 @@
ID: DOC_000010 | Version: 0.2.1 | Status: Draft
By: Codex (GPT-5)
# Usage
## Authentifizierung
- PAM-Login: `POST /login` mit Benutzername/Passwort. Liefert JWT und setzt Session-Cookie.
- OIDC-Login: `GET /login/oidc/start` startet Flow, Callback setzt Session-Cookie.
- Alle geschuetzten Endpunkte akzeptieren `Authorization: Bearer $TOKEN` oder Session-Cookie.
### Beispiel: Login und Token nutzen
```bash
token=$(curl -s -X POST -H "Content-Type: application/json" \
-d '{"username":"root","password":"example-password"}' \
http://localhost/login | jq -r .token)
curl -s -H "Authorization: Bearer $token" http://localhost/me
```
Hinweis: `jq` ist optional; ohne jq das Token manuell aus der JSON-Antwort lesen.
Login ist nur fuer erlaubte Nutzer moeglich (siehe `SKD_AUTH_ALLOWED_USERS` und `SKD_AUTH_ALLOWED_GROUPS`).
## Web-UI
- Aufruf: `http://localhost/`
- Login per PAM oder OIDC (wenn konfiguriert).
- Aktionen: Benutzer sperren/entsperren, Update-Status, Update-Check, Apply/Rollback.
## API-Endpunkte (Auszug)
### Health und Identitaet
- `GET /health` (ohne Auth)
- `GET /me`
### Benutzerverwaltung
- `GET /users`
- `POST /users/{username}/disable` mit JSON `{countdown?, sound?, message?}`
- `POST /users/{username}/enable`
Beispiel (disable):
```bash
curl -X POST -H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d '{"countdown":90,"sound":true,"message":"Bitte speichern"}' \
http://localhost/users/child1/disable
```
### Update-API (lokal)
Alle Update-Endpunkte erfordern Admin-Auth.
- `GET /update/status`
- `POST /update/enroll` (optional Body: `{ "enroll_token": "..." }`)
- `POST /update/check`
- `POST /update/apply` (optional Body: `{ "version": "x.y.z" }`)
- `POST /update/rollback`
- `GET /update/logs?limit=200`
Beispiel (Enrollment):
```bash
ENROLL_TOKEN="example-enroll-token"
curl -X POST -H "Authorization: Bearer $token" \
-H "Content-Type: application/json" \
-d "{\"enroll_token\":\"${ENROLL_TOKEN}\"}" \
http://localhost/update/enroll
```
Beispiel (Update-Check):
```bash
curl -X POST -H "Authorization: Bearer $token" http://localhost/update/check
```
Hinweis: Ohne gespeichertes Update-Token liefert der Check einen Fehler.
## CLI-Fallback (sk.sh)
Das Legacy-Script arbeitet direkt auf dem Host und benoetigt Root-Rechte.
Aufruf:
```bash
sudo ./sk.sh USERNAME disable|enable [countdown] [sound] [countdown_time_in_seconds]
```
Beispiel:
```bash
sudo ./sk.sh demo_user disable countdown sound 90
```

View File

@ -1,4 +1,5 @@
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Admin Token Operations

View File

@ -1,4 +1,5 @@
ID: DOC_000008 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
# Client Quickstart

View File

@ -1,4 +1,5 @@
ID: DOC_000003 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# OIDC End-to-End Validation (Kiddo)

View File

@ -1,4 +1,5 @@
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Third-Party API Guide

View File

@ -1,4 +1,5 @@
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Update API (Kiddo Backend)

View File

@ -1,4 +1,5 @@
ID: DOC_000004 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Client Update Flow (Kiddo)

View File

@ -1,4 +1,5 @@
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Update Status Reporting