docs: overhaul repository documentation
This commit is contained in:
93
docs/_archive/admin-token-operations.md
Normal file
93
docs/_archive/admin-token-operations.md
Normal 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.
|
||||
45
docs/_archive/client-quickstart.md
Normal file
45
docs/_archive/client-quickstart.md
Normal 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`.
|
||||
39
docs/_archive/oidc-validation.md
Normal file
39
docs/_archive/oidc-validation.md
Normal 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.
|
||||
137
docs/_archive/third-party-api.md
Normal file
137
docs/_archive/third-party-api.md
Normal 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
|
||||
```
|
||||
80
docs/_archive/update-api.md
Normal file
80
docs/_archive/update-api.md
Normal 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`).
|
||||
52
docs/_archive/update-client.md
Normal file
52
docs/_archive/update-client.md
Normal 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).
|
||||
30
docs/_archive/update-status.md
Normal file
30
docs/_archive/update-status.md
Normal 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.
|
||||
Reference in New Issue
Block a user