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.