Remote Hosts
How daemons identify and reach each other over iroh, the bilateral peer-trust model, and running sessions on another machine.
Two daemons that trust each other can create and run sessions across the pair — and it works wherever the machines are, not just on the same LAN. A typical setup: a workstation hosts the heavy sessions while you drive from a laptop.
Connections ride on iroh: each daemon has a stable
public-key identity (its EndpointId), and iroh handles finding the peer and
punching through NAT/firewalls (falling back to a relay when a direct path
isn't possible) — no ports to open. On the same network, daemons also find
each other automatically over mDNS and show up in actor servers list by name;
across networks you just need the peer's EndpointId.
A quick example
Say you're on your laptop and want a migration to run on your studio
workstation. Both machines just need the daemon up — any actor command starts
it.
First, read each machine's own EndpointId (the self row):
actor servers list # the `self*` row shows this daemon's EndpointId
Trust is mutual: each machine trusts the other by its EndpointId, which you exchange out of band (paste it over chat, copy it down, etc.). On laptop, trust studio:
actor servers trust <studio-endpoint-id> --name studio
And on studio, trust laptop:
actor servers trust <laptop-endpoint-id> --name laptop
With both sides trusting, the two daemons connect over iroh. Create a session
on studio with --host:
actor new migrate --host studio --prompt "Port the config loader to the new schema."
It runs in a worktree on studio and reports back like any local session. From
your main session you'd just ask — "spawn a session on studio to port the
config loader" — and main passes host for you.
Identity and discovery
Each daemon is identified by its EndpointId — the public half of an
Ed25519 key minted on first run and stored at ~/.actor/daemon.iroh.key. It's
stable for the life of the install, and it's what you trust and target.
actor servers list shows yourself, the peers you've trusted, and any peers
discovered on the local network (over mDNS), each with its state:
actor servers list
- self — this daemon (the
self*row, with your EndpointId). - discovered — seen on the LAN (with the name it advertises) but not yet trusted. Trust it by that name.
- trusted — you trust this peer.
- trusted, connected — you trust it and it trusts you back; the iroh channel is live and sessions can cross.
A peer you've trusted that hasn't trusted you back stays trusted but never reaches connected. A peer on a different network won't appear as discovered (mDNS is LAN-only) — get its EndpointId out of band (it isn't a secret) and trust that; iroh still connects across networks.
Trust is mutual
A connection only forms once each daemon has trusted the other. iroh
authenticates every connection to the peer's EndpointId, and each daemon's
accept path additionally requires that the connecting EndpointId is in its
trust store — so trusting one-way leaves the peer trusted but never
connected, and nothing can cross until the other side trusts you back.
On each machine, record the peer:
actor servers trust <endpoint-id> [--name <label>]
Pass the peer's EndpointId (64 hex chars), confirmed out of band — that's
the peer's real, cryptographic identity. --name is an optional friendly label
(it defaults to peer-<prefix>). Once a peer is listed, you can also refer to
it by that name in later commands. Run the command on the other machine too,
for the reverse direction.
Run sessions on a host
Target a connected host with --host <endpoint-id-or-name>. It's accepted by
the session commands — new, run, stop, discard, and show — so the
whole lifecycle works across the pair:
actor new migrate --host studio --prompt "Port the config loader."
actor run migrate --host studio "Now add tests."
actor discard migrate --host studio
The session lives in a worktree on the remote host and reports back the same
way local ones do. From your main session you don't type the flag: ask for work
"on studio" and main passes host to its new_session tool.
For a cross-host new, the remote can't see your local checkout, so it clones
the repo itself — actor sends your repo's origin URL and current branch, and
the host clones under its repo_dir (configurable in
settings.kdl). Run new --host from inside a
repo that has an origin the host can reach.
Trust is the gate for everything cross-host. Until both daemons trust each other, neither will provision sessions on the other.
Self-hosting discovery (optional)
By default, EndpointId → address resolution and relay use
number 0's public infrastructure. To point at your own
iroh-dns-server instead, set its origin domain in
settings.kdl:
dns_server "dns.example.com"
Revoking
Remove a peer from the trust store at any time:
actor servers untrust <endpoint-id-or-name>
After that, the daemon refuses to provision anything on it — and refuses its inbound connections — until you re-trust.