Skip to content

Security Model

DevCell treats the appliance as the authority. The Swift app and CLI are clients of celld; they render state and request operations, but they do not contain host policy or secret authority.

  • celld owns appliance identity, pairing, durable state, policy decisions, operation records, and backend orchestration.
  • The Swift app and devcell CLI talk to celld over Connect HTTPS and pin the appliance TLS fingerprint after pairing.
  • cell-agent runs inside CellOS and receives workspace execution plans from celld.
  • Project workloads run inside cells. Host support services can use NixOS/systemd/Quadlet, but they are not the isolation boundary.

Local pairing is exposed through HostService:

  1. NegotiateAPI
  2. GetPairingStatus
  3. StartPairing
  4. browser approval at /pair (from verification_uri_complete)
  5. CompletePairing

StartPairing returns a short-lived code, user_code, and verification links, then marks the request pending_confirmation. celld stores only a hash of the code. The Mac app opens the link in a fingerprint-pinned WebView; devcell host pair opens it in the default browser when possible.

When browser approval is unavailable, a local admin can recover with:

Terminal window
celld --approve-pairing <pairing-id>
celld --reject-pairing <pairing-id>

Set DEVCELL_PUBLIC_BASE_URL on appliances reached via Tailscale so verification links use the reachable hostname. After approval, CompletePairing returns a bearer token and celld stores only a token hash.

The daemon creates a self-signed TLS identity in the appliance data directory and serves HTTPS by default. InspectHost and RegisterHost expose the certificate fingerprint so clients can pin it. devcell host pair stores endpoint, host ID, certificate fingerprint, client ID, and bearer token in the user’s DevCell config directory with 0600 file permissions.

Local test loops can opt into plain HTTP with celld --http-dev. That mode is for development and tests, not appliance operation.

Terminal window
devcell host trust list
devcell host trust reset
devcell host tokens list
devcell host tokens revoke <client-id>
devcell host token rotate

Token rotation revokes the previous paired-client record and returns a fresh client ID/token pair. The Swift app stores equivalent trust material in Keychain.

Clients should ask for explicit confirmation before destructive or trust-changing actions:

  • destroy a cell
  • delete snapshots or workspace volumes
  • rotate host identity
  • reset pairing
  • import host-level secrets
  • enable LAN discovery
  • use a reduced-isolation backend

Create, start, stop, inspect, logs, and operation watch are normal paired-client actions.

Recovery is appliance-local. An admin shell or future appliance UI can reset pairing state, rotate identity, and inspect the SQLite-backed operation ledger. Restart reconciliation should fail interrupted privileged operations rather than replaying them blindly.

Terminal window
celld --print-recovery-info
celld --reset-pairing
celld --rotate-identity
celld --approve-pairing <pairing-id>
celld --reject-pairing <pairing-id>