Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

rex-iroh (or any rex-iroh compatible service) must be installed on both devices you wish to pair. You also need Rex itself: its server running on the device you want to reach, and the rex command on each device you connect from.

Installation

Cargo

cargo install rex-iroh --locked

Both methods build from source, which takes a few minutes.

Nix

# Test before installation
nix run git+https://tangled.org/isaaccorbrey.com/rex-iroh -- --help

# Install
nix profile install git+https://tangled.org/isaaccorbrey.com/rex-iroh

Starting the server

On the device whose Rex server you want to reach, start rex-iroh serve and leave it running:

rex-iroh serve
# forwarding to /home/you/.local/state/rex/run/server.sock
# allowlist   /home/you/.local/share/rex-iroh/allowlist
# id     c33be3af4267c19d409e48f837c269ff429cb0fbd8ab4ae0562d9dd584707e18
# ticket endpointadbtxy5pijt4dhkatzepqn6cnh7ufhfq7pmk...

serve finds your Rex server by asking rex whoami. If the forwarding to line names the wrong socket, pass the right one with --rex-server, in the same unix:// form that rex -S takes.

Nobody can connect while serve isn’t running, so once you’ve tried it out you probably want to run it as a service.

Pairing

On the device with the Rex server running (the issuer), ensure rex-iroh serve is running, then:

rex-iroh pair
# <qr code>
# rexpair:?ticket=...&secret=...
# expires in 120s

This emits an invite which can be used to pair the issuer with a joiner (any client device basically). The invite includes the iroh ticket for the issuer as well as a short-lived, single-use secret. Transfer it to the joiner via copy paste or by scanning the rendered QR code, then on the joiner (keep the single quotes, since the invite contains &):

rex-iroh join 'rexpair:?ticket=...&secret=...' --label "Isaac's Pixel 8" \
  --host desktop
# joining <...>
# check the other device shows: intact protect dutch want answer

--label is what the issuer calls the joiner, and --host is what the joiner calls the issuer, including as a Rex host. Both are optional. Without --host, the issuer goes by the start of its id, such as c33be3af42.

The security phrase printed is computed from the issuer’s and joiner’s identities and the secret. It’s very important to make sure this phrase matches before accepting the pair; if it doesn’t match, someone has stolen your invite and is attempting to pair instead of you, which will grant them any and all permissions your user account on the issuer has, or has tampered with your invite in some way.

Meanwhile, the terminal running rex-iroh pair on the issuer shows the request along with its own copy of the words. Answering anything but y declines it, and join fails with rejected: declined.

request from Isaac's Pixel 8
  device  695cc6e6d2
  words   intact protect dutch want answer
pair with this device? [y/N] y
paired; added to allowlist

Connecting

Once the issuer accepts, join saves its ticket under the name you gave, and adds a Rex host by that name, so rex -S desktop reaches the issuer:

accepted
saved desktop (c33be3af42)
added Rex host desktop → unix:///home/you/.local/share/rex-iroh/sockets/desktop-695cc6e6d2.sock
with `rex-iroh connect` running: rex -S desktop session ls

Rex keeps its hosts in your home, so your other devices see the host too. Its endpoint is a socket on this device, which other devices skip. If a host by that name already exists, join adds this device’s socket to it rather than making another. Pass --no-host to leave Rex’s hosts alone.

Then start connect and leave it running:

rex-iroh connect
# as 695cc6e6d2...
# desktop     /home/you/.local/share/rex-iroh/sockets/desktop-695cc6e6d2.sock

It opens a socket for every issuer you’ve joined, named after the issuer and this device, in the sockets directory of the state directory. Any rex command pointed at a socket talks to that issuer’s Rex server, whether through the Rex host, or with -S or REX_SERVER set to the socket’s unix:// URL. Issuers you join or forget later are picked up within a couple of seconds, without restarting connect, so it’s worth running it as a service too.

To reach a single issuer at a socket of your choosing instead, name it:

rex-iroh connect desktop --socket ~/.rex-desktop.sock

Pairing only works in one direction. The joiner can now reach the issuer, but the issuer can’t reach the joiner; for that, pair again with the roles swapped.