Remote Access
Run groove on a VPS and manage your agents from anywhere. No ports exposed to the internet. No tokens. No custom auth code. Zero attack surface.
How It Works
groove never opens ports to the public internet. Instead, it uses battle-tested transport layers — SSH tunnels and WireGuard (Tailscale) — to keep your daemon private.
Your laptop Your VPS
┌──────────┐ SSH tunnel ┌───────────────┐
│ Browser │◄───────────►│ groove daemon │
│ localhost│ encrypted │ 127.0.0.1 │
└──────────┘ └───────────────┘
Zero open portsThe daemon always binds to 127.0.0.1. Nothing reaches it from the public internet. Your SSH keys handle authentication. Your browser connects to localhost on your machine, and the tunnel forwards traffic securely to the VPS.
Setup
On Your VPS
SSH into your server and install groove:
sudo npm i -g groove-devStart the daemon in your project directory:
cd ~/my-project
groove startgroove detects that you're on a server and tells you exactly what to do next:
Daemon running on port 31415
To open the GUI, open a terminal on your Mac/PC and run:
npx groove-dev connect ubuntu@18.118.87.157VS Code Remote
If you're using VS Code Remote SSH, groove detects it automatically. VS Code forwards the port for you — just open http://localhost:31415 in your browser. No extra steps needed.
On Your Laptop
Install groove locally (one-time):
npm i -g groove-devConnect to your VPS:
groove connect user@your-server-ipThe GUI opens in your browser automatically. That's it.
When you're done:
groove disconnectOptions
| Flag | Description |
|---|---|
-i, --identity <keyfile> | SSH private key file (e.g., ~/.ssh/my-key.pem) |
--no-browser | Don't open the browser automatically |
SSH config aliases work too — if your ~/.ssh/config has a host entry, just use the alias:
groove connect my-vpsTailscale / LAN Access
For multi-device access (phone, tablet, other machines on your network), bind the daemon to a network interface:
groove start --host tailscale # auto-detects your Tailscale IP
groove start --host 192.168.1.5 # explicit IPOpen http://<ip>:31415 from any device on the same network. Tailscale handles auth via WireGuard.
The GUI shows a host badge in the header so you always know which instance you're looking at.
What's Blocked
groove rejects any attempt to expose the daemon directly to the internet:
groove start --host 0.0.0.0 # REJECTEDDirect internet exposure not supported.
Use `groove connect` (SSH tunnel) or `--host tailscale` instead.This is by design. Direct exposure requires custom auth, rate limiting, TLS certificate management — attack surface we refuse to create. SSH and WireGuard solve this better than we ever could.
Federation (Preview)
Coming Soon
Federation pairing and the security layer are built and working. Cross-server agent coordination (contracts, federated registry, GUI federation view) is coming in a future release.
Pair groove daemons across servers so they can securely communicate. This is the foundation for multi-server agent coordination.
Pairing
Pair two daemons on the same network (Tailscale or LAN):
groove federation pair 100.64.1.5Both daemons generate an Ed25519 keypair and exchange public keys. This is a one-time ceremony. Re-run to rotate keys.
Commands
groove federation pair <host> # pair with a remote daemon
groove federation unpair <id> # remove a paired peer
groove federation list # list paired peers
groove federation status # show daemon ID, keypair, peersWhat's Built
- Ed25519 keypair generation and secure key exchange
- Signed and verified cross-server messaging
- Replay protection (5-minute timestamp window)
- Peer management (pair, unpair, list)
- Full audit trail on both sides
What's Coming
- Agents sending and receiving typed contracts across servers
- Federated agent registry (see remote agents in your GUI)
- Contract lifecycle (requested, accepted, fulfilled)
- PM approval gate for incoming cross-server requests
- GUI federation view with server badges on agent nodes
Audit Log
Every state-changing operation is logged to .groove/audit.log.
groove audit # view recent entries
groove audit -n 50 # show last 50Example output:
2:14:32 PM agent.spawn id=a1 role=backend provider=claude-code
2:14:35 PM agent.spawn id=a2 role=frontend provider=claude-code
2:33:12 PM agent.rotate oldId=a1 newId=a3 role=backend
2:45:00 PM federation.pair peerId=f63dc52b14b9 peerHost=100.64.1.5The log is append-only with 0600 file permissions. Auto-rotates at 5MB.
Security Model
| Threat | Defense |
|---|---|
| Remote attackers | Zero open ports. Daemon binds to private interface only. |
| Network eavesdroppers | SSH (tunnel) or WireGuard (Tailscale) encryption. |
| Spoofed federation messages | Ed25519 signature verification on every message. |
| Replay attacks | 5-minute timestamp window. Old/future contracts rejected. |
| Malformed peer data | Public key validated at pairing. Peer IDs restricted to hex. |
| Path traversal | Peer IDs sanitized. No filesystem access across servers. |
| Privilege escalation | No auth code to exploit. Transport layer handles access control. |
What we don't defend against: Compromised SSH keys, root access to VPS, malicious AI provider responses (out of scope — groove is a process manager).
The principle: "There's nothing to attack" beats "we have a security system." groove has zero auth code. The transport layer does all the work.
