Remote Sessions
Remote sessions let you continue a conversation started on one device (e.g., your desktop) on another (e.g., your phone). The system uses a 6-layer security gate to ensure only authorized devices can join active sessions.
How it works
Section titled “How it works”- A session is created on the origin device (the desktop web UI, with the feature flag enabled)
- A transfer token is generated (
xfer_...) that expires after 2 minutes - The token is shared as a QR code or a
snippbot://deep link - The joining device (mobile) redeems the token and passes security checks
- Both devices can view the conversation in real time
Joining a session
Section titled “Joining a session”Deep link or QR code
Section titled “Deep link or QR code”Open a snippbot://session/xfer_... link on your phone — tap it in a message, or scan the origin device’s transfer QR code with your phone’s camera. The app opens directly to the join flow.
The app’s own QR scanner (on the pairing screen, Scan QR code instead) also recognizes transfer codes and routes them to the join flow.
Security gate
Section titled “Security gate”When joining a session, the app passes through up to 6 security layers. Each layer is configurable in session security settings.
| Layer | Check | Configurable |
|---|---|---|
| 1. Rate limiting | Max join attempts per time window | Server-side |
| 2. Device trust | Device must be in the daemon’s trusted device list | require_trusted_device |
| 3. Device fingerprint | Hardware fingerprint must match a known device | require_fingerprint_match |
| 4. TOTP verification | 6-digit authenticator code required | require_totp_on_join |
| 5. Owner approval | Session owner must approve the request | require_owner_approval |
| 6. Token validation | Transfer token must be valid and unexpired | Always enabled |
TOTP verification
Section titled “TOTP verification”When TOTP is required, you’ll see a 6-digit code entry screen:
- Open your authenticator app (Google Authenticator, Authy, etc.)
- Find the Snippbot entry
- Enter the 6-digit code in the app
- The code is verified against the daemon
Owner approval
Section titled “Owner approval”When owner approval is required:
- The daemon sends a Session Join Request push notification to the owner’s phone, showing the requesting device name and platform
- If the owner has Snippbot open on the Chat tab, an in-app approval banner appears with Approve and Deny
- On the joining device, you’ll see a waiting screen with a countdown to the request’s expiry
- If approved, you’re redirected to the conversation
- If denied, or if nobody responds within 120 seconds, the join attempt fails
Idle resume
Section titled “Idle resume”When you return to a joined conversation after being idle, the app may require re-verification:
- If
require_totp_on_idle_resumeis enabled, you’ll be prompted for a TOTP code after the idle threshold - The idle threshold defaults to 5 minutes and is set on the daemon (web UI chat settings)
- This prevents unauthorized use of an unattended device
Live session view
Section titled “Live session view”When you join a session from your phone:
- You see all messages in real time via a fan-out SSE stream
- Tool calls and agent responses stream live
- A session indicator pill shows at the top of the chat with the participant count
- Tap the pill to see all participants (device name, platform, role, and which device is the owner)
Session indicator
Section titled “Session indicator”Active sessions show a colored pill at the top of the chat:
| Color | Meaning |
|---|---|
| Green | Session active |
| Yellow | Less than 5 minutes until the session expires |
Approval banner
Section titled “Approval banner”When you’re the session owner and another device requests to join while Snippbot is open on the Chat tab, an approval banner slides in at the top:
- Shows the requesting device name and platform
- Approve and Deny buttons
- A countdown bar; the request expires on the daemon after 120 seconds
Security settings
Section titled “Security settings”Configure session security in Settings → Chat Sessions (the Chat Session Security screen).
Transfer mode
Section titled “Transfer mode”| Mode | Description |
|---|---|
| Explicit Only (default, recommended) | Session owner must manually generate a transfer code |
| QR Code + Deep Link | Transfer via QR scan or snippbot:// deep link |
| Automatic | Any paired device can join any conversation |
Security toggles
Section titled “Security toggles”| Setting | Default | Description |
|---|---|---|
| Require trusted device | On | Only trusted devices can join |
| Require TOTP on join | On | Authenticator code required to join |
| Require owner approval | On | Owner must approve each join request |
| Require TOTP on idle resume | On | Re-verify identity after idle timeout |
| Require fingerprint match | On | Verify device hardware fingerprint |
Timeout and lockout
Section titled “Timeout and lockout”| Setting | Range in app | Default | Description |
|---|---|---|---|
| Session expiry | 5–1440 min | 30 min | Sessions auto-expire after this duration |
| Max TOTP attempts | 1–10 | 5 | Device locked after this many failed codes |
| Lockout duration | 1–120 min | 15 min | How long a device stays locked |
Use the + / - stepper controls to adjust these values.
Troubleshooting
Section titled “Troubleshooting””Invalid transfer token”
Section titled “”Invalid transfer token””- Transfer tokens expire after 2 minutes — generate a new one
- Ensure the token starts with
xfer_ - Check that the session is still active on the origin device
- Make sure your phone is paired with the same daemon as the origin device
TOTP code rejected
Section titled “TOTP code rejected”- Verify your authenticator app’s time is synced (Settings > Time correction in most apps)
- Use the most recent code — codes rotate every 30 seconds
- After too many failures, your device may be locked out for the configured lockout duration
Approval timed out
Section titled “Approval timed out”- The owner needs Snippbot open on the Chat tab to see the approval banner
- The request expires after 120 seconds — the owner must respond within that window
- Try again after the request expires