Commit graph

2 commits

Author SHA1 Message Date
Denis Redozubov
9a3424d68c
feat(daemon): add sandbox runtime foundation (#3242)
* feat(daemon): add sandbox runtime foundation

* fix(daemon): preserve sandbox roots after agent env overrides

* fix(daemon): keep readiness probes pathless

* fix(daemon): harden headless run fallbacks

* fix(daemon): bootstrap sandbox runtime discovery

* fix(daemon): preserve explicit sandbox agent profile mounts

* fix(daemon): keep sandbox profile lookup run scoped

* fix(daemon): normalize sandbox data dir input

* fix(daemon): pin sandbox env roots to base data dir
2026-05-30 15:06:05 +00:00
Cursor Agent
bef9add981
feat(plugins): bound-API-token guard + bearer middleware (Phase 5)
Plan K1 / spec §15.7 / §16 Phase 5.

The daemon now ships a two-part hosted-mode safety floor:

1. startServer() refuses to start when OD_BIND_HOST is set to a
   non-loopback address and OD_API_TOKEN is unset. Loopback hosts
   (127.0.0.1 / ::1 / localhost) keep the existing zero-config
   desktop / dev experience. The error message points the operator
   at `openssl rand -hex 32` so the next attempt succeeds in one
   step.

2. When OD_API_TOKEN is set, every /api/* request must carry an
   `Authorization: Bearer <OD_API_TOKEN>` header. Three escape
   hatches:
     - Loopback peers (req.socket.remoteAddress matches
       isLoopbackPeerAddress) skip the check — the desktop UI / local
       CLI never need a bearer.
     - The /api/health, /api/version, and /api/daemon/status probes
       remain open so monitoring + cloud orchestrators (k8s readiness,
       Compose healthcheck) work without touching secrets.
     - Mismatched / missing headers return 401 API_TOKEN_REQUIRED.

This closes a previously documented Phase 5 hazard: an operator
spinning up the daemon with OD_BIND_HOST=0.0.0.0 (the docker-compose
default) without a token would have published an unsecured API.

Daemon tests: 1486 → 1490 (+4 cases on api-token-guard:
non-loopback bind without token rejected, public host with token
boots, loopback callers still pass without bearer, probes stay open).

Co-authored-by: Tom Huang <1043269994@qq.com>
2026-05-09 13:29:31 +00:00