Getting Started

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.