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

View File

@ -0,0 +1,93 @@
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Admin Token Operations
## Purpose
This document describes how operators create and manage pre-shared enrollment tokens for clients.
## Pre-Shared Token Creation
Operators generate a single-use enrollment token and share it out-of-band with the client.
Recommended properties:
- Single-use only
- Short TTL (e.g., 24h)
- Scoped to `project_id` and optional `client_id`/`software_id`
## Admin Interfaces
We provide both an Admin API and a CLI tool for token operations. A frontend will be added later.
### Admin User and Access
- An admin user must exist to operate token workflows.
- Initial access uses a local admin token.
- Later, admin auth will be integrated with the OIDC service.
### CLI and Admin API Capabilities
- Create enrollment tokens
- List token metadata (no plaintext output)
- Revoke tokens
- Export a token as a file for client installation
### Local Admin Token (Initial Phase)
- Admin requests must include `Authorization: Bearer <ADMIN_TOKEN>`.
- The admin token is stored locally (e.g., `.env`) and never committed.
Example `.env` (local only):
```
ADMIN_TOKEN=change-me-please
```
Minimal flow (first token):
1) Set `ADMIN_TOKEN` in `.env`.
2) Call `POST /v1/admin/enrollment-tokens` with the bearer token.
3) Export the returned one-time token to a file and hand it to the client.
## Admin API (Draft)
All admin endpoints are authenticated. Initial auth is local; later OIDC.
Base path:
- `/v1/admin`
Endpoints:
- `POST /v1/admin/enrollment-tokens`
- Create a pre-shared enrollment token.
- Request: `project_id`, optional `client_id`, optional `software_id`, optional `expires_at`.
- Response: token metadata + one-time plaintext token.
- `GET /v1/admin/enrollment-tokens`
- List token metadata (never return plaintext tokens).
- Supports filtering by `project_id`, `client_id`, `status` (active/used/expired).
- `POST /v1/admin/enrollment-tokens/{token_id}/revoke`
- Revoke a token (marks as revoked or sets `used_at`/`revoked_at`).
- `GET /v1/admin/enrollment-tokens/{token_id}/export`
- Export the one-time token to a file download (single use).
## CLI (Draft)
Example commands (names can be adjusted):
- `update-service admin token create --project <id> [--client <id>] [--software <id>] [--expires <iso8601>]`
- `update-service admin token list --project <id> [--status active|used|expired|revoked]`
- `update-service admin token revoke --id <token_id>`
- `update-service admin token export --id <token_id> --out ./enroll-token.txt`
Example format:
```
enroll_<random_32_bytes>
```
## Storage and Safety
- Store only a hash of the enrollment token (never plaintext).
- Track `created_at`, `expires_at`, and `used_at`.
- Deny enrollment if `expires_at` is exceeded or `used_at` is set.
## Rotation and Revocation
- Revoke enrollment tokens by invalidating their stored hash.
- Issue a new enrollment token if the previous one expires or is leaked.
## Distribution
Preferred channels:
- One-time install code (copy/paste)
- QR code
- Encrypted file included in an install bundle
## Audit Expectations
- Log token creation and enrollment usage for traceability.

View File

@ -0,0 +1,45 @@
ID: DOC_000008 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
# Client Quickstart
## Goal
Enroll a client, store the long-term token, fetch the manifest, and report status.
## 1) Get a Pre-Shared Token
Request a one-time enrollment token from an admin/operator.
## 2) Enroll and Receive Long-Term Token
```
curl -X POST https://update.wlkns.org/v1/enroll \
-H "Content-Type: application/json" \
-d '{
"project_id": "safe-kiddo-control",
"client_id": "kiddo-001",
"software_id": "kiddo-agent",
"enroll_token": "<pre_shared_token>"
}'
```
Store the returned token locally (file or secret store). Example:
```
echo "<long_term_token>" > ./update-token.txt
```
## 3) Fetch Manifest
```
curl -H "Authorization: Bearer $(cat ./update-token.txt)" \
https://update.wlkns.org/v1/projects/safe-kiddo-control/manifest
```
## 4) Report Status
```
curl -H "Authorization: Bearer $(cat ./update-token.txt)" \
-H "Content-Type: application/json" \
-d '{"project_id":"safe-kiddo-control","version":"0.1.2","status":"success","timestamp":"2025-12-30T10:00:00Z"}' \
https://update.wlkns.org/v1/projects/safe-kiddo-control/status
```
## Notes
- All endpoints require `Authorization: Bearer <token>` except `/v1/enroll`.
- Status values: `success`, `failed`, `in_progress`.

View File

@ -0,0 +1,39 @@
ID: DOC_000003 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# OIDC End-to-End Validation (Kiddo)
## Purpose
Validiere den OIDC-Login-Flow gegen einen realen oder Stub-Provider und dokumentiere Ergebnisse.
## Preconditions
- Kiddo laeuft und ist erreichbar (z.B. `http://localhost`).
- OIDC Provider oder Stub erreichbar.
- `SKD_AUTH_MODE=oidc` und `SKD_OIDC_*` gesetzt.
- Redirect-URI: `https://<device-host>[:port]/login/oidc/callback` ist registriert.
## Validation Steps
1. OIDC Start
- Aufruf: `GET /login/oidc/start`
- Erwartet: Redirect zum Provider, State-Cookie gesetzt.
2. Callback
- Provider ruft `GET /login/oidc/callback?code=...&state=...` auf.
- Erwartet: State valid, Token-Exchange erfolgreich, Session-Cookie gesetzt, Redirect `/`.
3. Session Check
- Aufruf: `GET /me` mit Cookie oder Bearer.
- Erwartet: `user` und `auth_mode=oidc`.
4. Allowlist
- Falls `SKD_AUTH_ALLOWED_USERS` gesetzt: nicht erlaubte User werden mit 403 abgewiesen.
## Results
- Datum: 28.12.2025
- Provider: nicht konfiguriert (IdP noch nicht bereit)
- Host/Redirect: n/a
- Ergebnis: Blocked (Service nicht erreichbar unter http://localhost/health)
- Fehlerbilder: curl (7) Couldn't connect to server
## Fallbacks bei unvollstaendigem IdP
- Discovery/JWKS fehlt: OIDC deaktivieren und PAM nutzen.
- DCR fehlt: Client manuell im IdP anlegen und `SKD_OIDC_*` setzen.
- TLS-Probleme: CA trusten oder PAM fuer Dev nutzen.

View File

@ -0,0 +1,137 @@
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Third-Party API Guide
## Purpose
This document explains how third-party services integrate with the Update Webservice: obtaining tokens, fetching manifests, downloading artifacts, and reporting status.
## Quick Start (First Client)
1) Request a pre-shared enrollment token from an admin/operator.
2) Enroll once to obtain a long-term token.
3) Store the long-term token locally and use it for all API calls.
## Base URLs
- Production: `https://update.wlkns.org`
- Staging: `https://staging.update.wlkns.org`
All endpoints are versioned under `/v1`.
## Authentication
All endpoints require `Authorization: Bearer <token>`.
### Enrollment (Pre-Shared Token -> Long-Term Token)
Clients obtain a long-term token by exchanging a pre-shared token provided by an admin/operator.
Request (example):
```
POST /v1/enroll
{
"project_id": "<project>",
"client_id": "<client>",
"software_id": "<software>",
"enroll_token": "<pre_shared_token>"
}
```
Response (example):
```
200 OK
{
"token": "<long_term_token>",
"scope": "read_manifest report_status",
"expires_at": "<iso8601 or null>"
}
```
Notes:
- Enrollment tokens are single-use and must be invalidated after a successful exchange.
- If the token is invalid or reused, the server responds with `unauthorized` or `invalid_payload`.
- Enrollment does not require an existing bearer token.
- If the client is already enrolled, the server responds with `already_enrolled` (HTTP 409).
## Client API (Read + Report)
### Get Manifest
```
GET /v1/projects/{project_id}/manifest
```
Response:
```
{
"version": "0.1.2",
"artifact_url": "https://update.wlkns.org/v1/projects/<project_id>/releases/0.1.2/artifact",
"sha256": "<hex>",
"sig_url": "<optional>"
}
```
Required scope: `read_manifest`
### Download Artifact
```
GET /v1/projects/{project_id}/releases/{version}/artifact
```
Required scope: `read_manifest`
### Report Status
```
POST /v1/projects/{project_id}/status
{
"project_id": "<project_id>",
"version": "<semver>",
"status": "success|failed|in_progress",
"timestamp": "<iso8601>",
"client_id": "<optional>",
"duration_ms": "<optional>",
"error_code": "<optional>"
}
```
Required scope: `report_status`
## Release API (Upload)
### Upload Release
```
POST /v1/projects/{project_id}/releases
Content-Type: multipart/form-data
```
Required scope: `upload_release`
Required fields:
- `version` (SemVer)
- `artifact` (file)
- `sha256` (hex)
Optional fields:
- `sig_url` or inline signature
- `key_id`
## Error Codes
Common error codes:
`unauthorized`, `rate_limited`, `not_found`, `invalid_payload`, `version_invalid`,
`version_exists`, `checksum_mismatch`, `signature_missing`, `signature_invalid`,
`payload_too_large`, `status_invalid`
## Rate Limits
Limits are tiered by scope. See `docs/architecture/openapi/paths/limits.yaml` for current values.
## Examples
Fetch manifest:
```
curl -H "Authorization: Bearer $TOKEN" \
https://update.wlkns.org/v1/projects/$PROJECT_ID/manifest
```
Report status:
```
curl -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project_id":"'"$PROJECT_ID"'","version":"0.1.2","status":"success","timestamp":"2025-12-30T10:00:00Z"}' \
https://update.wlkns.org/v1/projects/$PROJECT_ID/status
```

View File

@ -0,0 +1,80 @@
ID: DOC_000006 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Update API (Kiddo Backend)
## Purpose
Definiert interne API-Endpunkte fuer Update-Status, Check, Apply, Rollback und Logs.
## Endpoints
### POST /update/enroll
Body (optional):
```json
{ "enroll_token": "<one-time-token>" }
```
Antwort:
```json
{ "enrolled": true, "message": "Enrollment successful" }
```
### GET /update/status
Antwort:
```json
{
"current_version": "0.1.2",
"last_status": "success|failed|unknown",
"last_error": "<optional>",
"last_timestamp": "2025-12-28T12:34:56Z",
"enrolled": true
}
```
### POST /update/check
Antwort:
```json
{
"available": true,
"latest_version": "0.1.3",
"artifact_url": "https://update.wlkns.org/kiddo/kiddo-0.1.3.tar.gz",
"sha256": "<hex>",
"message": "<optional>"
}
```
### POST /update/apply
Body (optional):
```json
{ "version": "0.1.3" }
```
Antwort:
```json
{ "started": true, "message": "update started" }
```
### POST /update/rollback
Antwort:
```json
{ "started": true, "message": "rollback started" }
```
### GET /update/logs
Antwort:
```json
[
{
"timestamp": "2025-12-28T12:34:56Z",
"status": "success",
"message": "updated to 0.1.2",
"version": "0.1.2",
"device_id": "kiddo-001",
"error": null
}
]
```
## Notes
- Alle Endpunkte erfordern Auth (Session-Cookie oder `Authorization: Bearer <token>`).
- Apply/Rollback starten async; UI pollt /update/status.
- `/update/enroll` speichert das Update-Token lokal (siehe `SKD_UPDATE_TOKEN_FILE`).

View File

@ -0,0 +1,52 @@
ID: DOC_000004 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Client Update Flow (Kiddo)
## Purpose
Definiert den Client-seitigen Ablauf fuer das Pull-Update vom Update-Service.
## Manifest Format (JSON)
Beispiel:
```json
{
"version": "0.1.2",
"artifact_url": "https://update.wlkns.org/kiddo/kiddo-0.1.2.tar.gz",
"sha256": "<hex>",
"sig_url": "https://update.wlkns.org/kiddo/kiddo-0.1.2.sig"
}
```
## Flow (High Level)
0. Falls kein Token vorhanden ist: Enrollment durchfuehren (Pre-Shared Token -> Langzeit-Token).
1. Manifest abrufen (auth via Bearer Token).
2. `artifact_url` herunterladen.
3. SHA256 pruefen (Signatur optional).
4. In Staging-Verzeichnis entpacken.
5. Service stoppen.
6. Atomic swap: aktuelles Verzeichnis sichern, Staging nach `/opt/sk` verschieben.
7. Service starten.
8. Bei Fehlern Rollback auf Backup.
## Prototype Script
- `scripts/update_client.sh` implementiert den Flow als CLI-Prototyp.
- Erfordert `curl`, `tar`, `sha256sum`, `python3` und `systemctl`.
## Rollback
- Wenn Start fehlschlaegt: Backup nach `/opt/sk` zurueck, Service neu starten.
- Backup-Verzeichnis benoetigt genuegend Speicher.
## Security Notes
- Artefakte muessen checksum-verifiziert sein.
- Token-Handling ueber `SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE`.
- Enrollment nutzt einen Pre-Shared Token und speichert das Langzeit-Token lokal.
## Constraints
- Update-Service ist extern (update.wlkns.org).
- Service muss als root stoppen/starten koennen.
## Status Reporting
- Status wird per HTTP POST an `${SKD_UPDATE_SERVICE_URL}/v1/projects/${SKD_UPDATE_PROJECT_ID}/status` gemeldet.
- Schema siehe `docs/update-status.md`.
- Lokaler Status/Logs liegen unter `/var/lib/skd` (konfigurierbar via ENV).

View File

@ -0,0 +1,30 @@
ID: DOC_000005 | Version: 0.2.1 | Status: Draft
Archived – superseded by new documentation.
By: Codex (GPT-5)
# Update Status Reporting
## Purpose
Definiert das Status-Schema fuer Update-Resultate und den Uebertragungsweg.
## Status Schema (JSON)
```json
{
"project_id": "safe-kiddo-control",
"client_id": "<hostname>",
"version": "0.2.1",
"status": "success|failed|in_progress",
"timestamp": "2025-12-28T12:34:56Z",
"duration_ms": 1234,
"error_code": "<optional>",
"reason": "<optional>"
}
```
## Transport
- HTTP POST an `${SKD_UPDATE_SERVICE_URL}/v1/projects/${SKD_UPDATE_PROJECT_ID}/status`
- Auth: Bearer Token (`SKD_UPDATE_TOKEN` oder `SKD_UPDATE_TOKEN_FILE`)
## Notes
- Statusmeldungen sind best-effort; Fehler beim Senden blockieren kein Update.
- Reporting wird nur gesendet, wenn ein Update-Token vorhanden ist.