fix(acpmux): use fresh delivered machine secrets when launching agents

Merged
TE
8d ago
+145-0

Cloud-delivered secrets take effect before new acpmux sessions start

cmux cloud deliver-secrets writes ~/.config/cmux/machine-secrets.env after the machine config's shell hook is installed. acpmux caches the login-shell environment and previously fingerprinted/watched only shell startup files, not the machine files themselves. A newly launched Claude/other harness could inherit stale or missing credentials after delivery, rotation or revocation (private HQ #5066).

Fix: include ~/.config/cmux/machine.env and machine-secrets.env in the login-shell fingerprint/watcher. Track file metadata from the last successful import, including inode/ctime on Unix so an atomic same-sized replacement changes the stamp. Immediately before either direct ChildAgent::spawn_with or durable Hub::spawn_hosted_child snapshots its environment, coalesce and await a bounded fresh login-shell import when these machine files changed. If the import fails, refuse the new child/host rather than pass old credentials. No new daemon argv, on-disk schema, or public RPC is required; existing running agents are not retroactively updated.

Tests and isolation

  • Test-only commit 4ef44409 adds two unit regressions: machine files are included in the startup watcher/fingerprint and a pure metadata stamp detects delivery, rotation and revocation. Subsequent source commits implement the behavior; a further Unix-only check covers same-size atomic replace.
  • The same async freshness gate is placed next to each actual process-environment snapshot, shared by direct children, CLI/probes and durable hosted children. Ordinary shell profile edits retain the existing background refresh contract.
  • No secret contents, bearer values or paths are logged; the helper reads only metadata.
  • Target: feat-cmux-next, where CloudMachineConfig installs machine.env sourcing hooks. Old Cloud machines without these files keep their original behavior.

Observed / Not run

  • Inspected acpmux login_env.rs, agent/command.rs, ChildAgent::spawn_with, hosted launch and CloudMachineConfig receiver/hook implementation; preserved their ownership.
  • Test-only regression committed before implementation, but no red Rust execution was performed. Hosted Rust verification has not run yet; do not infer a passed test/compile from these commits.
  • Need exact-head hosted acpmux tests and compile on Linux/macOS (the repo explicitly forbids local maintainer Cargo use): ./scripts/verify-cmux-tui-hosted.sh --filter stamp_changes_for_delivery_rotation_and_revocation, then the relevant full daemon check. Confirm results on the current head before merging.
  • Regular PR for review; leave unmerged. No production deploy, remote machine upgrade, provider or credential access.

Changelog

Fixed: newly launched Cloud machine agents reload delivered or revoked secrets rather than reading acpmux's stale login environment.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes newly launched Cloud machine agents picking up stale or revoked secrets after cmux cloud deliver-secrets or credential rotation.

acpmux cached the login-shell environment and only watched shell startup files, so a new agent could inherit credentials that changed after daemon startup. machine.env and machine-secrets.env are now part of the startup fingerprint and watcher; their metadata (including inode/ctime on Unix to catch same-size atomic replacement) is recorded on each successful import. Before any direct or hosted child spawn, acpmux awaits a fresh login-shell import when those files changed, and refuses the spawn if the import fails. Existing running agents are unaffected, and machines without these files keep their previous behavior.