# Safe Kiddo Daemon Service to lock/unlock local user accounts on kids' laptops with countdown, notifications, optional sound, and shutdown. Provides a REST API plus a small web UI for remote control; retains the original `sk.sh` script as legacy/CLI fallback. ## Features - Disable/enable accounts, terminate sessions, optionally trigger shutdown. - Desktop notifications and optional sound during countdown. - Login-protected API with minimal web UI (PAM auth for root users, bearer token for calls). - Systemd-managed service, virtualenv-based deploy, remote update script. - Dry-run mode to validate flows without touching accounts. ## Quick Start (Local/Target Device) ```bash git clone /opt/sk cd /opt/sk ./scripts/install.sh sudo systemctl status skd.service ``` Then open `http://localhost/` and log in via PAM (default) to start quickly. ## Configuration Set in `/etc/skd/env` (see `env.example`): - PAM-Login ist immer aktiv. OIDC wird zusaetzlich angeboten, wenn konfiguriert. - `SKD_AUTH_SECRET`: HMAC secret for bearer tokens/cookies (set a strong value). - `SKD_TOKEN_TTL_SECONDS`: token lifetime (default 900s). - `SKD_AUTH_ALLOWED_USERS`: optional comma list of accounts allowed to log in (used for PAM and as an allowlist for OIDC claims). - `SKD_AUTH_ALLOWED_GROUPS`: groups whose members may log in (PAM only, default `sudo`). - `SKD_AUTH_PAM_SERVICE`: PAM service name; Ubuntu/Debian uses `/etc/pam.d/skd` (created by `scripts/install.sh`), other distros may prefer `login` or `sshd`. - `SKD_OIDC_*`: `ISSUER`, `CLIENT_ID`, `CLIENT_SECRET`, `REDIRECT_URI`, `SCOPES` to point at your OIDC provider; set `SKD_SESSION_COOKIE_SECURE=true` for HTTPS. - OIDC dynamic registration helper: `scripts/register_oidc_client.sh` (requires `OIDC_INITIAL_ACCESS_TOKEN` and `SKD_OIDC_ISSUER`; uses `SKD_OIDC_REDIRECT_URI` for the redirect). Run once during setup if your provider issues initial access tokens for client creation. - `SKD_ALLOWED_USERS`: optional comma list to limit manageable accounts (must exist on the system). - `SKD_DEFAULT_COUNTDOWN`, `SKD_DEFAULT_SOUND`, `SKD_NOTIFY_TIMEOUT`: behavior defaults. - `SKD_DRY_RUN=true` to test without real account changes or shutdown. - `SKD_SOUND_PLAYER`/`SKD_SOUND_FILE`, `SKD_NOTIFY_SEND_PATH` if defaults differ. - Update client: - `SKD_UPDATE_URL` (default `https://update.wlkns.org`) - `SKD_UPDATE_TOKEN` (API token for update service) - `SKD_UPDATE_INTERVAL` (seconds; default 3600) - `SKD_UPDATE_STATUS_URL` (default `https://update.wlkns.org/status`) Notes: - `./scripts/install.sh` will create `/etc/skd/env` from `env.example` if missing (edit afterwards) and ensure the `skd` service user/group exist. ## OIDC Setup OIDC ist optional. PAM bleibt immer verfuegbar; `SKD_AUTH_MODE` ist optional. 1. Issuer muss der externen URL des Providers entsprechen (TLS trust erforderlich). 2. OIDC Client registrieren (DCR), z.B.: ```bash export SKD_OIDC_ISSUER="https://auth.example.org" export SKD_OIDC_REDIRECT_URI="https:///login/oidc/callback" export OIDC_INITIAL_ACCESS_TOKEN="" ./scripts/register_oidc_client.sh ``` 3. Danach in `/etc/skd/env` setzen: ``` SKD_AUTH_MODE=oidc SKD_OIDC_ISSUER=... SKD_OIDC_CLIENT_ID=... SKD_OIDC_CLIENT_SECRET=... SKD_OIDC_REDIRECT_URI=... SKD_OIDC_SCOPES=openid profile email SKD_SESSION_COOKIE_SECURE=true ``` Hinweise: - Redirect-URI muss exakt sein (keine Wildcards). - Bei Host/Port-Aenderung neu registrieren und neue Credentials setzen. - Allowlist fuer OIDC: `SKD_AUTH_ALLOWED_USERS` prueft `preferred_username`, `email` oder `sub`. ## Running - Service: managed by systemd; `./scripts/install.sh` writes the unit dynamically to `/etc/systemd/system/skd.service` with the current repo path and restarts it (runs as root for PAM). - Manual run: `./scripts/run.sh` (uses `.venv`, defaults to `0.0.0.0:80`). - Login (PAM): `curl -X POST -H "Content-Type: application/json" -d '{"username":"root","password":"..."}' http://localhost/login` - Login (OIDC): open `http://localhost/login/oidc/start` → provider → redirected back with session cookie set. - Health: `curl -H "Authorization: Bearer " http://localhost/health` ## OIDC Validation & Fallbacks - Validierungsschritte: `docs/oidc-validation.md` (State, Token-Exchange, Claims, Cookie). - Falls Discovery/JWKS nicht verfuegbar: OIDC deaktivieren und PAM nutzen. - Falls DCR nicht verfuegbar: Client manuell im IdP anlegen und `SKD_OIDC_*` setzen. - Bei Self-Signed TLS: CA im System trusten oder in Dev PAM nutzen. ## API (Bearer token via `/login`) - `GET /users` → `[{user, logged_in, account_locked}]` (manageable system users; excludes root) - `POST /users/{name}/disable` with JSON `{countdown?, sound?, message?}` - `POST /users/{name}/enable` - `GET /health` - `GET /me` (returns current user + auth mode when a session/bearer token is present) Example: ```bash token=$(curl -s -X POST -H "Content-Type: application/json" -d '{"username":"root","password":"..."}' http://localhost/login | jq -r .token) curl -X POST -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ -d '{"countdown":90,"sound":true}' \ http://localhost/users/child1/disable ``` ## Web UI Served at `/`. Nutze den Button „Login via OIDC“ (setzt Session-Cookie) oder das PAM-Formular, falls OIDC deaktiviert; danach werden verfügbare System-User angezeigt und Aktionen senden Token/Cookies automatisch. ## Updates - Remote update via SSH: `ssh user@kid-laptop 'cd /opt/sk && ./scripts/update.sh'` (fetch/reset to `origin/main`, reinstalls deps, restarts service). - Manual: `git pull && source .venv/bin/activate && pip install -r backend/requirements.txt && sudo systemctl restart skd` ## Deployment (zip/SSH) - Quick copy: create `sk_deploy.zip` (already in repo root) and unzip on target under `/opt/sk`, then refresh venv deps and restart service. - Scripted deploy: edit `deploy_hosts.yml` (host/user/port/install_dir/service user/group), then run `./scripts/deploy.sh `; accepts JSON configs too. Requires SSH access and `sudo` on target. - After deploy on target: `sudo -u skd /opt/sk/.venv/bin/pip install -r /opt/sk/backend/requirements.txt && sudo systemctl restart skd.service` ## Security Hardening - Restrict access to API/Web UI to LAN/VPN; firewall the port. - Set a strong `SKD_AUTH_SECRET`; rotate tokens by changing the secret. - Create dedicated `skd` user/group; no login shell. - Configure sudoers minimally: allow `skd` to run `usermod -L/-U`, `pkill -KILL -u`, `shutdown now`, and sound/notify binaries if needed (no full passwordless sudo). - Consider mTLS or IP allowlisting for added protection. ## Legacy Script `sk.sh` remains for direct SSH use. Plan to replace its logic with API-backed helpers; keep it as emergency fallback.