Files
kiddo/README.md

6.6 KiB

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)

git clone <repo> /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) 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.:
export SKD_OIDC_ISSUER="https://auth.example.org"
export SKD_OIDC_REDIRECT_URI="https://<device-host>/login/oidc/callback"
export OIDC_INITIAL_ACCESS_TOKEN="<initial-access-token>"
./scripts/register_oidc_client.sh
  1. 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 <token>" 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:

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 <host-name>; 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.