# Roaming ~ — arch-dev v3 Turn neovim-ide into your **roaming home directory**. SSH in from any device, and every server on your tailnet feels like home: one keyring, one shell history, one set of dotfiles, reachable from anywhere. This is what makes neovim-ide more than another riced nvim install — it's a control plane for your whole fleet. --- ## The Model ``` You (phone / tablet / chromebook) ↓ ssh nvimide.tailnet.ts ← your roaming home (this container) ↓ ssh / sshfs over tailnet ┌──────────┬──────────┬──────────┐ mail proxy dev (any host) ``` You live in nvimide. Files live on remote hosts (mounted via sshfs when you want them). Commands run on remote hosts via short per-host functions. Keys never leave nvimide — agent auth handles remote login, remote `sudo` still prompts (the security boundary stays intact). --- ## Files | File | Purpose | |---|---| | `~/.config/roaming/hosts` | Registry — one line per host (source of truth) | | `~/.config/roaming/roaming.zsh` | Engine — generates host functions, mount helpers | | `add_new_machine.sh` | Onboard a new host (key + register + verify) | --- ## Usage ### Run commands on a host Each registry entry becomes a command. Dumb by design — pipes and redirects run **locally**, exactly like plain ssh (predictable, no surprises). ```bash mail # interactive shell on mail mail tail -f /var/log/mail.log # TTY allocated — -f works mail sudo systemctl restart postfix # remote sudo prompts for password proxy sudo systemctl reload caddy dev docker compose logs -f ``` ### Mount a host's filesystem ```bash mount_host mail # sshfs the registered path → /workspace/mail ls /workspace/mail/etc/postfix/ unmount_host mail # clean unmount (handles stale mounts) ``` Mounts use `reconnect,ServerAliveInterval=15,ServerAliveCountMax=3` so a network blip errors out in ~45s instead of freezing your shell forever. ### Status & reload ```bash roaming-status # list hosts + which are mounted roaming-reload # re-read registry after editing hosts by hand ``` ### Add a new machine ```bash add_new_machine.sh mail mail.tailnet.ts root / # 1. ssh-copy-id (one password prompt) # 2. appends to ~/.config/roaming/hosts # 3. verifies key-based login ``` After that, `mail` works in the next shell (or after `roaming-reload`). --- ## Registry Format ``` # name fqdn user mount mail mail.tailnet.ts root / proxy proxy.tailnet.ts admin /etc/caddy dev dev-server.tailnet.ts youruser ``` - `user` optional — defaults to `$ROAMING_DEFAULT_USER` or current user - `mount` optional — omit if you only run commands, never mount --- ## Onboarding a Fresh Client The whole point: a new device needs almost nothing. 1. Install your SSH key to reach nvimide.tailnet.ts 2. SSH in — you're home. Dotfiles, history (atuin), keys, the works. No per-device key sprawl. nvimide holds the fleet keyring; clients only need to reach nvimide. --- ## Gotchas (learned, baked in) - **Pipes are local.** `mail tail -f log | grep err` greps locally. Want it remote? Quote the whole pipeline: `mail 'tail -f log | grep err'`. - **Stale mount frozen?** `fusermount3 -uz /workspace/` force-clears it. - **`tail -f` / `htop` / sudo need a TTY** — handled (`ssh -t` always). - **Agent forwarding (`-A`) is intentionally OFF** — a compromised remote could abuse a forwarded agent. Add per-host later only if you need to hop. --- ## Roadmap (future hardening) - **SSH CA + OIDC (Authelia)** — replace `authorized_keys` with short-lived certs issued after Authelia auth. Collapses key management fleet-wide. Deferred: keys stay as the stable fallback until the cert flow is proven. - **autofs** — system-level lazy mount/unmount (60s idle auto-unmount) as an alternative to manual `mount_host`. - **atuin** — single shell-history brain in nvimide, DB in the postgres cluster; retire atuin-server.