forked niri forked from okami.mom/niri

feat(split): authenticated executor + coral-executor nixos module #62

targeting main from deleted fork:feat/control-executor-split
Merged opened by and assigned to callie.on-her.computer
targeting main from deleted fork:feat/control-executor-split

Physically separate the control plane (LLM loop/session/memory/compaction) from the tool executor (shell/file/image/computer) across an authenticated REST boundary, so they can run on two machines. The control plane holds continuity; the executor is replaceable hands that can die and reconnect without amnesia.

what's here #

Auth on the REST boundary

  • ToolClientHttpServer (executor) gains an optional shared bearer token: every request must present Authorization: Bearer <token> or 401. Constant-time comparison (timingSafeEqual).
  • HttpToolClient (control plane) sends the token on /health + /tools calls. It already degrades gracefully — on an unreachable executor it marks disconnected and returns an error result instead of throwing, so reef dying = lost hands, not death.
  • apps/client (the coral-executor entry) reads the token via --token-file (agenix) or NIRI_EXECUTOR_TOKEN; warns loudly if unset.
  • control plane resolves NIRI_EXECUTOR_TOKEN_FILE / NIRI_EXECUTOR_TOKEN.

NixOS

  • new coral-executor binary wrapper (apps/client entry).
  • new services.coral-executor module: listenAddress / port / tokenFile / capabilities / hashline, with an assertion that refuses to bind a tokenless executor to a non-loopback address (verified it fails correctly).
  • services.coral gains executorTokenFile → exposes NIRI_EXECUTOR_TOKEN_FILE to workers.

verification #

  • npm run typecheck green across all packages.
  • 4 new tests: server accepts/rejects bearer token (missing / wrong scheme / wrong token / correct), client sends the header. All green.
  • nix flake show evals; module ExecStart + both assertion branches verified via nix eval.

Companion nix-config PR moves the control plane to homura and the executor to reef.

Commits 0