Managed Client Concepts
Managed client is Nanami’s CLI-first onboarding path for macOS/Linux without desktop GUI apps.
Canonical API Contract
Login:
POST /api/v1/auth/login
Managed client lifecycle:
POST /api/v1/client/devices(create/enroll)POST /api/v1/client/devices/:id/config(refresh config)POST /api/v1/client/devices/:id/heartbeat(updatelast_seen)GET /api/v1/nodes/:id(status source of truth)
Enrollment Flow
nanami loginauthenticates and stores session tokens in~/.nanami/config.json.nanami up --node-name ... --network ...creates a managed node and receives a server-generated WG payload.- CLI writes deterministic local config:
~/.nanami/wireguard/nanami0.conf
nanami up --applyattemptswg-quick up.- CLI posts heartbeat so server-side status remains current.
nanami statusreads server truth and local state summary.
Local Secret Storage
~/.nanamidirectory mode:0700~/.nanami/config.jsonmode:0600~/.nanami/wireguard/*.confmode:0600
Private keys are generated and stored locally by CLI. Only public key rotation is sent to control-plane.
Config Generation vs Apply
--print-configprints a sanitized config (PrivateKeyredacted).- Config generation always writes to local path even when apply fails.
--applyrequireswg-quickand OS-level permissions.
If apply cannot proceed:
- CLI prints exact install hint (
wireguard-tools) and fallback instructions. - No silent failure; errors include command output and next-step remediation.
Error Contract
Managed-client endpoints follow stable response classes:
401:{ "error": { "code": "unauthorized", "message": "..." } }403:{ "error": { "code": "forbidden", "message": "..." } }404:{ "error": { "code": "not_found", "message": "..." } }400:{ "error": { "code": "validation_error", "message": "..." } }422validation schema:{ "error": { "code": "VALIDATION_ERROR", "message": "Validation failed", "fields": [...] } }