Coven Pocket (OpenCoven/coven-pocket) is growing a companion mode that talks to the daemon from another device. The MVP ships transport-agnostic: the daemon's TCP listener stays loopback-only (coven daemon --tcp, guarded by ensure_loopback_addrs), and the phone reaches it over the user's Tailscale network or an SSH tunnel (ssh -L 7777:localhost:7777 mac), probing GET /health for reachability. Tracked there as OpenCoven/coven-pocket#6.
That MVP deliberately punts authentication to the network layer. This issue tracks the design for a first-class remote listener so companion clients don't need a hand-managed tunnel.
Requirements
- Opt-in listener — e.g.
coven daemon --remote <bind> or config; loopback-only remains the default. The existing --allow-host TCP guard stays for the local case.
- Mutual authentication — bearer token is the floor (per-device tokens minted by a pairing command, stored hashed), with a path to mTLS. A
coven daemon pair flow could print a QR code embedding host + token for the phone.
- Transport security — TLS on the remote listener (self-signed cert pinned at pairing time is acceptable for v1), or explicit documentation that the listener must sit behind Tailscale/WireGuard.
- Protocol handshake — companion clients must complete the
coven.daemon.v1 handshake before any session API; unauthenticated connections get /health only (consider redacting pid/version there).
- Scoped authorization — a paired device should be limitable to session attach/observe vs. full control (approvals, input forwarding).
- Revocation —
coven daemon devices list|revoke <id>.
Non-goals (for this design)
- Internet-facing relay/broker infrastructure; assume direct reachability.
- Multi-user daemons; the trust boundary stays "one user's devices".
Prior art in-repo
crates/coven-cli/src/daemon.rs: TCP transport with loopback guard, slowloris timeouts, body caps — the remote listener can extend this.
docs/AUTH.md hardening notes on socket ownership (fail-closed uid check) — the remote equivalent needs the same fail-closed posture.
Coven Pocket (OpenCoven/coven-pocket) is growing a companion mode that talks to the daemon from another device. The MVP ships transport-agnostic: the daemon's TCP listener stays loopback-only (
coven daemon --tcp, guarded byensure_loopback_addrs), and the phone reaches it over the user's Tailscale network or an SSH tunnel (ssh -L 7777:localhost:7777 mac), probingGET /healthfor reachability. Tracked there as OpenCoven/coven-pocket#6.That MVP deliberately punts authentication to the network layer. This issue tracks the design for a first-class remote listener so companion clients don't need a hand-managed tunnel.
Requirements
coven daemon --remote <bind>or config; loopback-only remains the default. The existing--allow-hostTCP guard stays for the local case.coven daemon pairflow could print a QR code embedding host + token for the phone.coven.daemon.v1handshake before any session API; unauthenticated connections get/healthonly (consider redacting pid/version there).coven daemon devices list|revoke <id>.Non-goals (for this design)
Prior art in-repo
crates/coven-cli/src/daemon.rs: TCP transport with loopback guard, slowloris timeouts, body caps — the remote listener can extend this.docs/AUTH.mdhardening notes on socket ownership (fail-closed uid check) — the remote equivalent needs the same fail-closed posture.