Make relay opt-in when pairing devices (#2706)
* feat: make relay opt-in for device pairing * fix(relay): keep pairing state authoritative * fix(relay): refresh pairing state across transports * fix(onboard): honor explicit relay opt-out * fix(relay): surface transport startup failures * fix(pairing): gate offers for older daemons * test(cli): rely on real pairing transport coverage * fix(cli): report live relay without a pid file * fix(relay): synchronize config during daemon startup * fix(relay): preserve mutability for ignored overrides * fix(cli): use reachable daemon for pairing * fix(app): redirect invalid pair device routes * fix(pairing): support remote host device pairing Keep Pair Device host-relative through the existing settings and daemon RPC flow. Route CLI output through an injected adapter so workflow tests do not mutate process globals. * fix(pairing): validate pairing destinations Expose the host-relative Pair Device flow on every supported app platform. Reject a reachable daemon whose identity does not match the requested Paseo home before reading or mutating its pairing state. * fix(pairing): render QR codes across platforms Generate SVG text without DOM or canvas and render it through the existing cross-platform SVG stack. * fix(cli): pair from persisted relay state Allow explicit relay pairing while the daemon is stopped when relay is already enabled in persisted configuration.
This commit is contained in:
+5
-1
@@ -200,9 +200,13 @@ Use `PASEO_HOME` to run multiple isolated daemon instances.
|
||||
Get an offer URL from the daemon you want to control:
|
||||
|
||||
```bash
|
||||
paseo daemon pair --json # prints { url, qr, ... }
|
||||
paseo daemon pair # asks before enabling relay, then prints the QR and link
|
||||
paseo daemon pair --relay # enables relay without prompting
|
||||
paseo daemon pair --json # structured output; never prompts
|
||||
```
|
||||
|
||||
Relay is off for new installations. In non-interactive or JSON mode, a disabled relay returns a `RELAY_DISABLED` error; pass `--relay` to provide explicit consent. Relay pairing is end-to-end encrypted. See [Security](/docs/security).
|
||||
|
||||
Use it from anywhere:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -187,11 +187,30 @@ A `password=` in the URI always wins over the env var, so you can keep `PASEO_PA
|
||||
|
||||
In the mobile app, enter the password in the direct connection setup screen.
|
||||
|
||||
## Relay
|
||||
|
||||
New homes write `daemon.relay.enabled: false`. Paseo asks before enabling relay when you pair a device; existing homes keep their saved value. See [Security](/docs/security) for relay encryption and direct connection alternatives.
|
||||
|
||||
Set the persisted value in `config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"daemon": {
|
||||
"relay": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`PASEO_RELAY_ENABLED=true|false` overrides the persisted value for that daemon launch. The matching `paseo daemon start --relay` and `--no-relay` flags have the same authority. Remove the launch override before changing relay from Paseo Desktop or `paseo daemon pair --relay`.
|
||||
|
||||
## Common env vars
|
||||
|
||||
- `PASEO_HOME`, set Paseo home directory
|
||||
- `PASEO_PASSWORD`, on the daemon, the password to require (plaintext, hashed at startup); on the CLI, the password used to connect when the host URI doesn't include one
|
||||
- `PASEO_LISTEN`, override `daemon.listen`
|
||||
- `PASEO_RELAY_ENABLED`, enable or disable the outbound relay for this daemon launch
|
||||
- `PASEO_HOSTNAMES`, override/extend `daemon.hostnames`
|
||||
- `PASEO_ALLOWED_HOSTS`, deprecated alias for `PASEO_HOSTNAMES`
|
||||
- `PASEO_WEB_UI_ENABLED`, enable or disable the daemon-served web UI
|
||||
|
||||
@@ -14,7 +14,7 @@ Paseo runs your coding agents on your machine and gives you a mobile, desktop, w
|
||||
|
||||
Download from [paseo.sh/download](https://paseo.sh/download) or the [GitHub releases page](https://github.com/getpaseo/paseo/releases). Open it and you're done.
|
||||
|
||||
The desktop app bundles its own daemon and starts it automatically, no separate install required. On first launch you'll see a brief startup screen, then connect from your phone using **Settings → your host → Connections → Pair a device**.
|
||||
The desktop app bundles its own daemon and starts it automatically, no separate install required. On first launch you'll see a brief startup screen, then connect from your phone using **Settings → your host → Pair Device**.
|
||||
|
||||
## Server / CLI
|
||||
|
||||
@@ -25,7 +25,7 @@ npm install -g @getpaseo/cli
|
||||
paseo
|
||||
```
|
||||
|
||||
Paseo prints a QR code in the terminal. Scan it from the mobile app, or enter the daemon address manually from another client.
|
||||
Paseo starts the daemon locally, then asks whether to enable the end-to-end encrypted relay and print a pairing QR code. If you decline, enter the daemon address manually over TCP, Tailscale, or another VPN.
|
||||
|
||||
The daemon can also serve the browser web app itself, so you can use the full UI without the hosted app. See [Self-hosting the web UI](/docs/web-ui).
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ Clients connect to the daemon over WebSocket. There are two ways to establish th
|
||||
|
||||
The relay is the simplest way to connect from your phone. It requires no VPN setup, no port forwarding, and no firewall configuration. The daemon can stay bound to localhost or a socket file, it connects _outbound_ to the relay, and your phone meets it there. The official relay server is the open-source Elixir service at [getpaseo/paseo-relay](https://github.com/getpaseo/paseo-relay).
|
||||
|
||||
Relay is off on new installations. When you pair a device from `paseo`, `paseo daemon pair`, or Paseo Desktop, Paseo asks before enabling it. Choosing not to enable relay leaves the daemon available for direct TCP, Tailscale, or other VPN connections and does not create a pairing QR code. Use `--relay` with the CLI pairing or startup command to opt in without an interactive prompt.
|
||||
|
||||
> **The relay is designed to be untrusted.** All traffic between your phone and daemon is end-to-end encrypted. The relay server cannot read your messages, see your code, or modify traffic without detection. Even if the relay is compromised, your data remains protected.
|
||||
|
||||
### How it works
|
||||
|
||||
@@ -76,7 +76,7 @@ By default the daemon listens on `127.0.0.1:6767`, reachable only from the same
|
||||
paseo daemon start --web-ui --listen 0.0.0.0:6767
|
||||
```
|
||||
|
||||
> **Anyone who can reach the listening address can use your agents.** Before you bind beyond localhost, set a password and review your host allowlist. The relay (the default mobile pairing path) avoids this entirely by keeping the daemon bound to localhost, see [Security](/docs/security).
|
||||
> **Anyone who can reach the listening address can use your agents.** Before you bind beyond localhost, set a password and review your host allowlist. The relay pairing path avoids this entirely by keeping the daemon bound to localhost, see [Security](/docs/security).
|
||||
|
||||
Two things to configure when you expose the daemon directly:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user