Skip to content

Design: authenticated remote listener for the daemon (companion clients) #463

Description

@BunsDev

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).
  • Revocationcoven 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions