Installation¶
Setting up roamd takes three steps: make an account, install roamd on a computer, and approve that computer. It takes about five minutes.
1. Account 2. Install 3. Approve
(in your browser) (on the computer) (both together)
app.roamd.co.uk --> paste one command --> roamd login
email + password into its terminal click Approve
save recovery key check the 6 digits match
type y
The web address is now app.roamd.co.uk. Your account and paired computers stay on the same service. Sign in again with your master password; add a new passkey and allow notifications again if you use them. Browser-only settings and an installed app may need setting up again at the new address.
Older roamd installations can keep connecting through the previous address during the handover. A future daemon release will update their saved address while keeping their pairing. The web change alone does not update installed daemons.
browser -> app.roamd.co.uk -> same account and computers
older roamd -> previous address -> same service
1. Make an account¶
- Go to app.roamd.co.uk and enter the preview access password we gave you.
- Choose Create account. Enter your email and a master password (at least 10 characters; a few random words work well).
- Check your email for a 6-digit code from roamd and type it in. This proves the email is yours; the account only exists once you do. No email? Check your spam folder, or choose Email me a new code. (If that address already has an account, the email says so instead.)
- You'll see a recovery key like
ABCD-EFGH-…(9 groups of 4). Write it down or save it in your password manager. If you ever forget your master password, it's the only way back in. We can't reset it for you.
2. Install roamd on the computer you want to reach¶
Open a terminal on that computer and paste one of these. You don't need to be an administrator.
Linux or Mac (Terminal):
curl -fsSL https://app.roamd.co.uk/install.sh | sh
Windows (PowerShell):
irm https://app.roamd.co.uk/install.ps1 | iex
The installer checks the download against the published checksum before installing it, and stops if it doesn't match. (That catches a damaged or incomplete download. The checksum comes from the same website, so the signature check on later updates is the stronger protection; see Updating roamd.) You can also copy these commands from Open sessions → Add a machine in the app.
When it has finished installing, the installer goes straight on to step 3 for you. It
prints a boxed message, "Next: registering this machine, if it isn't
already. Starting roamd login for you", so you can see that the second step has begun. You don't type roamd login
yourself. This happens every time you run the installer: if the computer is already registered,
roamd says so and leaves it alone, and if roamd was installed but never logged in (or you
logged out), you go through the whole setup. If there's no keyboard to ask you on, it tells you to run roamd login --hub https://app.roamd.co.uk
yourself.
tmux (Linux and Mac). roamd keeps your sessions in tmux, so they survive a dropped
connection. If the computer doesn't have it, the installer deals with it before the login
step. On a Mac, if you're at the keyboard, it asks "Install tmux with Homebrew? [Y/n]";
press Enter to say yes. If Homebrew isn't there it first asks "Install Homebrew first?"
(Homebrew's own installer; it asks for your Mac's password and can take a few minutes), then
tmux. If you say no, or an install fails, or there's no keyboard to ask on, the last thing the
installer prints is how to get tmux yourself (brew install tmux, with Homebrew's address if
you don't have it, or sudo port install tmux with MacPorts; on Linux,
sudo apt install tmux). You can skip it: roamd then gives you a plain shell.
Permission questions on a Mac. roamd itself never looks at your screen, camera or microphone. A program you run in a session might, though (an AI app taking a screenshot, for example). If it does, the Mac asks on its own screen. The question names that program, or tmux (which runs your sessions), not roamd. Say yes only if you know which program wants it and why. Saying no never stops roamd working.
a program in a session asks to record the screen
|
v
the Mac asks on its own screen, naming that program (or tmux), not roamd
|-- Deny --> only that program goes without; roamd and your sessions carry on
'-- Allow --> that program may record the screen from now on
tmux on Windows (psmux). Windows has no tmux of its own, so roamd uses
psmux, a tmux that runs on Windows itself (it installs as
tmux.exe). If the PC doesn't have tmux, the Windows installer asks "Install psmux with
winget? [Y/n]". If you say no, there's no winget, or it fails, the last thing printed is how to
install it yourself (winget install psmux, or with Scoop). Sessions that psmux already has show
up in the list when you connect, as tmux sessions do elsewhere. Bringing sessions back after a
restart works on Windows too, with psmux's own versions of the two add-ons (see below); they
need PowerShell 7 (the installer offers it with winget if it's missing; it looks on the PATH and in the usual install places: Program Files, your user folder, the Store, a preview, dotnet and Scoop). Not yet tried on
a real Windows PC.
Updating psmux on Windows.
Two screens on one session (roamd and a psmux window at the PC) need psmux 3.4.0 or later;
3.3.8 flickers. Check yours with psmux -v. winget install psmux may not have the newest
version yet, so use the zip from the psmux releases
(psmux-v3.4.0-windows-x64.zip: psmux.exe, pmux.exe, tmux.exe). Building with cargo install
psmux needs Visual Studio's C++ tools and fails without them (msvcrt.lib).
1. Find old copies: Get-Command psmux -All | Select Source
2. Remove them: winget uninstall --id marlocarlo.psmux (and delete any
.cargo\bin\psmux.exe; an old copy earlier on the PATH wins)
3. Unzip to: %LOCALAPPDATA%\psmux-3.4.0
4. Put it on the PATH: [Environment]::SetEnvironmentVariable("Path",
"$env:LOCALAPPDATA\psmux-3.4.0;" +
[Environment]::GetEnvironmentVariable("Path","User"), "User")
5. Open a NEW PowerShell, check: psmux -v (3.4.0)
6. Stop the old server: psmux kill-server
7. Sign out of Windows and back in, so the roamd service sees the new PATH
8. Rejoin the session from roamd
psmux -v shows "not recognized" in the window you did this in? That window predates the PATH
change: open a new one. Not yet tried on a real Windows PC beyond this.
Where it goes, so typing roamd just works:
who runs it roamd goes to on the PATH?
--------------------------- ---------------------- ---------------------
you (Linux, Mac) ~/.local/bin added for you
root (Linux, Mac) /usr/local/bin already, for everyone
you (Windows) your AppData folder added for you
Administrator (Windows) Program Files\roamd added, for everyone
Running the Windows installer again on a computer that already has roamd updates it: it stops the old roamd, puts the new one in place, and starts it again by itself.
If it was added for you, open a new terminal (or run the export PATH=… line the installer
prints) before typing roamd.
Running as root or Administrator? roamd refuses to log in as the all-powerful account
unless you ask for it with --allow-root, because every browser you approve would then get
full control of the computer. The installer's automatic roamd login can't be told that, so as
root it stops with that message; run roamd login --allow-root yourself if that's what you want.
3. Approve the computer¶
-
On the computer,
roamd loginstarts by itself when the installer finishes. (If you need to do it again later, run:)roamd login
On a Linux desktop, roamd locks its keys in your desktop keyring and says so. It then
only starts while you're logged in to the desktop. For a computer that must be reachable
after a restart with nobody logged in, run roamd login --no-keyring instead.
2. It prints a link. Open it in your browser (logged in to roamd) and click Approve.
3. Your browser and the computer each show a 6-digit pairing code. Your browser then says
Not finished yet: go to the computer's terminal to compare the codes and finish. If they match, type
y on the computer. If they don't, type n: something is wrong, and nothing is trusted.
If your browser shows no code and says to type n, do that too.
Your browser can't see what you type there. Once the computer has connected, the page
notices by itself, says the computer is approved and takes you to Open sessions.
4. That's it. Once you type y, roamd sets itself up to run all the time, so there is
nothing to start by hand. It ends with Done. This browser can now open a terminal
here.
The computer now shows as online in Open sessions.
Reinstalling a computer you already have. A fresh install is a new identity, so it would normally show up as a second computer. If you already have one with the same name, the approval page says so and offers Replace name. Choose that and the new install takes over the old entry: same place in the list, same tab, same sharing. Choose Add as a new machine if it really is a different computer. Replacing is only offered for your own computers, and you still compare the pairing codes as usual.
Signing in to Codex on a server¶
After installing Codex through roamd, choose Log in to Codex. It uses a device code, so the server does not need a browser or a desktop. Open the address shown in your own browser, sign in and enter the one-time code displayed in the terminal.
Log in to Codex -> server shows a link and code
-> open link in your browser -> enter code -> server signs in
If device-code login is unavailable, enable it in your ChatGPT security settings, or ask your workspace administrator to allow it. See OpenAI's headless login guidance.
4. Running all the time¶
Setting up in step 3 already did this for you. It's the same as running:
roamd service install
roamd now starts when you log in to that computer, and restarts if it ever crashes. (If you
set it up as root with --allow-root, it's a system service that starts when the computer
boots, with nobody logged in.) On Linux, Mac and Windows it also sets up two tmux add-ons
(tmux-resurrect and tmux-continuum, or psmux-resurrect and psmux-continuum on Windows; they
need an internet connection to fetch) so your tmux sessions come back after the computer
restarts, or after you log in again on Windows, screen text included; turn that off with
roamd tmux-restore off. If that step fails it says so, and the rest still works. Restarting
or updating roamd leaves tmux running on Linux. (Set it up with an older roamd? Run the
command once more.) On a
Linux server that nobody logs in to, it also prints one extra command to keep it running.
If roamd's keys are in your Linux desktop keyring, it waits for you to log in to the
desktop, then connects by itself.
If that last part couldn't be done, login still worked, and roamd tells you so and says to
run roamd service install to try again (or roamd run to start it just for now).
Removing roamd from a computer¶
On the computer, run:
roamd uninstall
It asks first, then takes the computer off your account, stops and removes the background
service, takes roamd's tmux add-on lines out of your tmux config, deletes roamd's settings
and keys, and deletes the roamd program. Your tmux sessions and your files are not touched.
It ends with a list of what was done, and says so plainly if a step couldn't be. (On Windows
a running program can't delete itself, so it tells you which file to delete yourself. As
root, add --allow-root.)
roamd uninstall
|
v
"Remove roamd from this machine?" -- n --> nothing changed
| y
v
off your account -> service removed -> settings deleted
-> program deleted
To skip the question, add --yes. If the computer can't reach the internet, it still removes
everything on the computer; remove it from Open sessions afterwards.
Setting up a server you reach with SSH¶
If you can log in to a Linux or Mac server with SSH (a password or a key), roamd can do steps 2 to 4 there for you, either from this website or from your own computer.
From the website¶
In Open sessions → Add a machine → Server (SSH), enter the server's address, your username and your password (or paste a private key), then Set up.
YOUR BROWSER our website your server
runs SSH itself -- locked --> passes the -- locked --> SSH port
bytes along
1. shows the server's fingerprint: you check it matches
2. only then logs in (your password stays locked inside SSH)
3. installs roamd there, which asks to be approved
4. you click Approve; the page compares the two pairing codes
itself, and shows you it doing so
5. roamd starts as a service on the server
The dialog shows only the step you are on (a row of four marks the way: Your server, Check it, Install, Approve), so the address, username and password go out of sight once sent and you never have to scroll to find what to do next. When the pairing check finishes, it stays up for a moment so you can read the result. Afterwards Finish and Finish + New Session are the only things left.
The server's own messages appear in a terminal window marked Live output from you@your-server. You don't type anything there: the page answers for you.
Why the page can check the codes itself. The pairing code proves nobody, not even roamd's website, swapped anything while your browser and server were introduced. Here the two codes reach your browser by two different routes:
your server ===== straight, sealed SSH =====> this browser
| (the code it worked out) ^
| |
+---> roamd's website ----------------------+
(its ID and a secret; the browser works
out its own code from them)
same code? yes: the page tells your server "yes, trust it"
no: the page tells it "no"; nothing is trusted
The SSH route is the connection you checked with the fingerprint, so roamd's website can't change what comes along it. You'd only be comparing two things the page already has, so it compares them for you: a big green The codes match or a red The codes are different. If they differ, don't go on from that network. The check runs slowly enough to watch, on a computer or a phone: each code travels its route on the diagram, then the two are compared digit by digit.
- Check the fingerprint. It's how you know you've reached your real server and not an
impostor. Your hosting provider usually shows it; or, on the server, it's what
ssh-keygen -lfprints for the files in/etc/ssh/ending_key.pub. If it doesn't match, choose It doesn't match: nothing is sent. - A private key is safer than a password. Even an impostor that got past the fingerprint check couldn't use a key login to get into your server. Keys with a passphrase work too; the passphrase is used only inside the page.
- Nothing you enter is saved, unless you tick Save these login details in my vault. It starts unticked. Left unticked, the password and key are forgotten when setup ends. Ticked, the address, username and password or key (with its passphrase) are locked into your vault once the server is set up, and shown under the machine's ⋯ → Details. roamd's website only ever holds them locked. The catch: anyone who can unlock your roamd account can then also log in to that server, so only tick it if you want that.
tick box off (default) -> setup -> login forgotten
tick box on -> setup -> login locked in your vault
-> ⋯ -> Details -> see / copy / forget
From your own computer¶
One command on your own computer does the same. Your computer needs roamd installed too (step 2 above).
roamd install-over-ssh me@my-server
YOUR COMPUTER THE SERVER
------------- ----------
roamd install-over-ssh -- ssh --> install roamd
(asks your ssh roamd login --+
password, if any) |
prints a link |
YOUR BROWSER |
click Approve, check the <-------------------------+
6 digits match ---- type y in the same window ---->
start roamd as a service
- It uses your normal
ssh, so your keys,~/.ssh/configand password prompts all work. Extra ssh options go after--, for exampleroamd install-over-ssh me@my-server -- -p 2222 -i ~/.ssh/work_key. - Add
--name NAMEto choose the name shown in Open sessions (it's the server's own name otherwise). - It needs the
sshprogram (OpenSSH) on your own computer. - On a server nobody logs in to, it tries to keep roamd running after you disconnect, and if
it can't without a password it prints one more command; run it with
ssh -t me@my-server '…'. - Logging in as
root? Add--allow-rootbefore the server, for exampleroamd install-over-ssh --allow-root root@my-server. Otherwise it stops before installing anything. With it, every browser you approve gets full control of that server. - Windows servers: use the PowerShell install command over ssh by hand for now.
Hostname handover¶
The canonical origin is https://app.roamd.co.uk. The account database and device
registrations are retained. Browser storage and permissions belong to the origin;
sign in with the master password, register passkeys again and re-enable push at the
new origin. Existing passkeys were scoped to the previous hostname. Reinstall the
browser app at the new address if needed.
The previous hostname temporarily proxies machine traffic to the same hub and redirects HTML browser navigations to the canonical site. Updated installers pass the hub explicitly so new registrations use it even with the currently published daemon. The next daemon release rewrites only the previous official HTTPS hub address in saved registrations, preserving the device identity, token and storage protection. Custom hub addresses are unchanged. That daemon change is not released yet.
browser -> canonical origin -> existing hub and database
older daemon -> previous hostname -> existing hub
updated daemon -> canonical origin -> existing hub
Requirements¶
| Supported | |
|---|---|
| Browser | Current Chrome, Edge, Firefox, Safari (WebAssembly and WebCrypto random numbers) |
| Linux | x86_64 and aarch64; static musl binaries, no dependencies |
| macOS | Apple Silicon and Intel; not notarised (install from Terminal: Gatekeeper blocks browser downloads of unsigned binaries) |
| Windows | x86_64 (ARM64 via emulation); Windows 10 or later |
macOS and Windows builds are cross-compiled and not yet tested on real hardware.
Account¶
The account is prepared in the browser: email plus master password (minimum 10 characters). The browser derives keys locally and creates the vault. The hub emails a one-time code and creates the account only when it's entered; the browser then shows the recovery key once. See Accounts and the vault.
Installing the agent¶
curl -fsSL https://app.roamd.co.uk/install.sh | sh # Linux, macOS
irm https://app.roamd.co.uk/install.ps1 | iex # Windows PowerShell
installer
|
+-- detect OS + CPU (uname / PROCESSOR_ARCHITECTURE)
+-- download roamd-<os>-<arch> and SHA256SUMS over HTTPS
+-- verify SHA-256 against the same site's list; abort on
| mismatch or missing entry (no signature check here)
+-- install to:
| root (id -u = 0) /usr/local/bin (on the default PATH)
| other users ~/.local/bin
| Windows, elevated %ProgramFiles%\roamd (added to Machine PATH)
| Windows, not elevated %LOCALAPPDATA%\roamd\bin (added to User PATH)
+-- Unix, folder not on PATH: append one guarded line to
| ~/.profile, and ~/.bash_profile, ~/.bash_login, ~/.zprofile
| where they exist (once; ROAMD_NO_MODIFY_PATH=1 skips this)
+-- no tmux on PATH: macOS + a keyboard -> if no brew, ask to run Homebrew's
| installer (ROAMD_HOMEBREW_INSTALLER overrides its address), then ask,
| `brew install tmux` (answers from the keyboard, default yes); otherwise,
| or if that fails, print the install hint as the very last output
+-- Windows, no tmux on PATH -> if winget is there and a keyboard, ask,
| `winget install --id marlocarlo.psmux`; otherwise, or if that fails,
| print the install hint as the very last output
+-- Windows, no PowerShell 7 -> same, `winget install --id Microsoft.PowerShell`
| (needed by the psmux session-restore add-ons)
+-- Windows: a running roamd of the same path is stopped before it is replaced
+-- every install: print a banner, then run `roamd login --if-needed`
| (does nothing if this computer is already registered;
| answers come from the keyboard, even when piped into sh;
| Windows: if already registered, then `roamd service install` so the
| new roamd is running)
+-- the installer itself creates no service (login does, after `y`)
The added line is case ":$PATH:" in *":DIR:"*) ;; *) export PATH="DIR:$PATH" ;; esac # roamd,
so it does nothing when the folder is already on the PATH, and re-running the installer
doesn't add it twice (the same approach rustup takes).
Binaries and SHA256SUMS are also linked from Open sessions → Add a machine.
Enrolling a machine¶
roamd login [--hub URL] [--name NAME] [--no-keyring] [--allow-root] [--config DIR]
On Linux, login seals the host key and device token with a key kept in the desktop keyring
(Secret Service API) when one is running and unlocked, and says so; --no-keyring keeps
owner-only files. Settings keep the way they were sealed: a later login can move plain
files into the keyring, but nothing moves settings already in the keyring back out (to
switch, remove the settings folder, or run roamd uninstall, and log in again; see
Safety on your machines). --no-keyring has no
effect on macOS and Windows, which always use their own secure storage. As root or
Administrator, login refuses unless given --allow-root.
Replacing. When a machine asks to join, the approval page is also told which of the
account's own devices have the same name (ASCII case-insensitive), with their identity and
whether they are online. Approving can name one of them to replace. The hub accepts that only
if the device belongs to the same account and has the same name; otherwise it answers "not
found" and changes nothing. It then keeps the device id, name, shares, mutes and push settings,
stores the new host key and token hash (so the old install's token stops working), clears the
last-seen record, and cuts any live tunnel and cached status under the old install. It is
logged as machine_added. The new host fingerprint is pinned in your vault; other browsers
that had the old one pinned will warn that the machine's identity changed, which is correct.
After a successful y, login runs service install itself (same --allow-root) and ends
with Done. This browser can now open a terminal here.; if the service step fails it adds
Couldn't set roamd up to run in the background: … with the reason, and says to run
roamd service install or roamd run. The registration is kept either way.
machine (roamd login) hub browser (logged in)
--------------------- -------------------- ------------------------
create host key (Ed25519)
random secret, commitment
register name, host key,
commitment --> pending approval
<-- short code (short-lived)
print approve link open link
see name, host fp,
commitment
Approve: send browser
pubkey + own secret
device record created <--
collect result --> device id, token,
<-- browser pubkey, secret
reveal own secret --> --> check it matches
the commitment
show pairing code show pairing code
(6 digits from SHA-256 over both fingerprints and both secrets)
user types y
save browser key -> authorized_keys
save device.json (hub, id, token)
The machine trusts nothing until the user confirms on the machine that the pairing codes match. A hub that swapped either key would produce different codes, and because the machine's secret stays hidden until both keys are fixed, it can't search for a key that happens to give the same code (see Connecting to a machine).
The y is typed locally and never sent. After showing the code, the approval page asks the
hub for the device list every two seconds; once that machine is online it shows "approved"
and moves on to Open sessions. If you typed n, the machine never connects and the page stays
on the code.
Codex authentication after installation¶
The Log in to Codex action runs codex login --device-auth in the terminal of
the machine where Codex was installed, on Unix and Windows. It explicitly selects
device-code authentication rather than relying on a browser opening on that machine
and a localhost OAuth callback. The user approves the displayed code in their own
browser; Codex manages the resulting credentials on the remote machine.
roamd login button -> remote Codex device-code flow
-> browser approval -> Codex stores credentials remotely
Device-code authentication must be enabled in the ChatGPT account's security settings or permitted by the workspace administrator. Browser regressions verify the command and originating terminal; they do not authenticate a real OpenAI account. See OpenAI authentication documentation.
Running and autostart¶
roamd run [--config DIR] [--allow-root]
roamd service install | uninstall | status [--config DIR] [--allow-root]
| OS | Service | Location |
|---|---|---|
| Linux | systemd user unit, Restart=on-failure |
~/.config/systemd/user/roamd.service |
| macOS | LaunchAgent, KeepAlive on non-zero exit |
~/Library/LaunchAgents/uk.co.roamd.roamd.plist |
| Windows | Task Scheduler task at logon and every minute (starts roamd only if it isn't running), least privilege, restart on failure | task roamd |
service install needs a registered machine (run roamd login first), and prints where the
service's messages go: the journal on Linux (journalctl --user -u roamd, without --user
for the system unit), a log file under the user's Library/Logs on macOS, and, on Windows, a note
that none are kept (the task has no console) with where logins are recorded.
As root or Administrator, service install refuses unless given --allow-root; with it, the
service itself runs roamd run --service --allow-root:
| OS | Service as root / Administrator | Location |
|---|---|---|
| Linux | systemd system unit, User=root, NoNewPrivileges=yes, WantedBy=multi-user.target (starts at boot, no lingering needed) |
/etc/systemd/system/roamd.service |
| macOS | LaunchDaemon in the system domain, HOME set |
/Library/LaunchDaemons/uk.co.roamd.roamd.plist, log /var/log/roamd.log |
| Windows | the same logon task at HighestAvailable |
task roamd |
service uninstall and status pick the same kind of service by whether they run as root,
without the flag. roamd uninstall (see above) does need --allow-root as root.
The Linux unit stops only roamd's own process (KillMode=process), so tmux sessions started
through roamd survive a restart or update of roamd; units installed earlier need
roamd service install again. On every OS, service install also turns on bringing
tmux sessions back after a restart (tmux-resurrect and tmux-continuum, or psmux-resurrect and
psmux-continuum on Windows, which need PowerShell 7; see
Safety on your machines)
unless it is already on or the user's tmux config already loads those plugins; if fetching the
plugins fails, service install still succeeds and says so. roamd tmux-restore
[on [--no-screen-text]|off|status] changes it by hand.
Linux user services stop at logout unless lingering is enabled
(sudo loginctl enable-linger $USER). With keys in the desktop keyring, roamd run waits
(retrying periodically) until the keyring is unlocked, so a service started at boot comes up
once the user logs in to the desktop; service install points this out. The service runs roamd run --service, which exits 0
when stopping on purpose (machine removed, unsafe settings) so it isn't restarted in a loop.
The macOS and Windows service definitions are unit-tested but not yet run on real systems.
Remote setup over SSH, from the web app¶
The browser runs the SSH client (the same WebAssembly SSH as for machines) over a WebSocket that the hub splices to the server's TCP port. The hub sees only SSH ciphertext.
1. hub check: signed in, own page, address and port acceptable
2. probe connection: SSH key exchange only; the client refuses
every host key, so the server's fingerprint is learned
before any authentication is attempted
3. user compares the fingerprint (or stops: nothing sent)
4. real connection pinned to that fingerprint; password or
key authentication; PTY + the shared setup script
5. the approval code is read from the output and approved
in the same page (one click)
6. the page reads "Pairing code: …" from the PTY output,
compares it with its own, shows the comparison, and
answers y (equal) or n (different) on the PTY
Why automatic comparison loses nothing: the code the machine prints arrives inside the SSH
session whose host key the user pinned in step 3, so the hub can't alter it, while the
browser's code is derived from what the hub relayed (fp(H), Nm). That is exactly the
two-channel comparison the pairing code exists for; a human reading both numbers off the
same page would add nothing. If the server never prints its code in time, the
page answers n. When the user runs roamd login themselves, the two codes are on
different screens and the user still compares them.
The comparison is paced so it can be watched on any screen size: the answer y/n is only
sent once both codes have travelled their routes on the diagram and every digit has been
compared. Reduced-motion settings skip the pauses. The panel holds only short step titles;
the reasoning lives here in the manual.
Relay restrictions, enforced by the hub on every connection:
- signed-in account, and only from roamd's own page;
- the target must resolve to public internet addresses: private, loopback, link-local, shared, reserved and documentation ranges, IPv6 forms that wrap IPv4 addresses, and the hub's own addresses are refused (the vetted address is the one connected to);
- the SSH port or high ports only;
- the far end must greet as an SSH server, or the connection is dropped;
- a limited number of setups per account per hour, and a maximum session length.
Trust: on a first connection there is no known host key, so a hub (or anyone on the path) could present its own key. The fingerprint comparison is the defence; with public-key authentication an impersonator gains nothing reusable, while a password would be exposed to it. The UI says so. Passwords, keys and passphrases are used in memory only and cleared after the attempt, unless the user ticks Save these login details in my vault (default off). Then, once setup finishes and this page approved the machine, the browser seals one vault item per machine holding the address as typed, username, the password or the private key as pasted (still under its passphrase) plus the passphrase, the pinned SSH host fingerprint and the time. It is encrypted like every vault item, so the hub stores only ciphertext. If the machine was approved elsewhere the page can't tie the login to a machine, so nothing is saved and the status says so. Trade-off: whoever unlocks the vault (password, recovery key or passkey) also gets that server login.
setup finished + box ticked + approved here
-> seal {address, user, password | key [+ passphrase], fingerprint, time}
-> vault item for that machine -> hub stores ciphertext
Details -> unseal in browser -> masked until revealed
Forget / Remove machine -> item sealed empty at a new revision
Remote setup over SSH, from the command line¶
roamd install-over-ssh [--hub URL] [--name NAME] [--allow-root]
USER@SERVER [-- SSH OPTIONS]
Runs the local OpenSSH client once:
ssh [SSH OPTIONS] -t -- USER@SERVER "sh -c '<script>'". The server comes after --, so it
can't be read as an ssh option (a server beginning with - is refused anyway), and -t
gives roamd login a terminal for the pairing confirmation. The script, run by sh
whatever the remote login shell is, stops at the first failure:
- without
--allow-root(the web app's Allow root / Administrator tick box): ifid -uis 0, printThis is the root account, …and exit 1, before downloading anything; - fetch
install.shfrom the hub (a failed download stops here) and run it with downloads from the same hub (the installer verifies the binary's SHA-256 as usual), into/usr/local/binfor root and~/.local/binotherwise; later steps run that binary by its full path; roamd login --no-keyring [--allow-root] --hub HUB [--name NAME]: the normal enrolment, approved in the browser and confirmed withyafter comparing pairing codes (this already installs the service, as above);- on systems with
loginctl, a best-effortloginctl enable-linger(ignored if it needs a password), so a user service survives logout; roamd service install [--allow-root], which prints thesudo loginctl enable-lingercommand if the service would still stop at logout. The last line isroamd setup finished.
Every user-supplied value is single-quoted for the shell, so a name can't add commands. Credentials stay with ssh: roamd never sees the password or key. Remote Windows isn't supported by this command.
Settings folder¶
| OS | Default |
|---|---|
| Linux | $XDG_CONFIG_HOME/roamd or ~/.config/roamd |
| macOS | ~/Library/Application Support/roamd |
| Windows | %LOCALAPPDATA%\roamd (local, not roaming) |
--config DIR or ROAMD_CONFIG_DIR overrides it.