Skip to content

Remote access (tunnel) security

Settings walkthrough: Remote access guide (Public internet tab).

Remote access exposes your local gateway on the public internet via FRP (frp.xopc.ai). Treat it as high risk.

Defaults

  • Tunnel is off on install and on gateway / Electron startup.
  • frpc is downloaded only when you start remote access (tunnel start or the settings UI).
  • Electron release builds do not bundle frpc.
  • Cached binary: {stateDir}/bin/frpc (default ~/.xopc/bin/frpc; honors XOPC_STATE_DIR).
  • While a tunnel is active, the gateway sets XOPC_FRPC_PATH to the resolved binary; it is cleared on stop.

Broker registration secret

Connecting to the production broker (frp.xopc.ai) requires a registration secret (not the gateway Bearer token).

SourcePriorityNotes
XOPC_TUNNEL_REGISTRATION_SECRET1 (wins)Shell / Electron parent env; overrides config
tunnel.registrationSecret in xopc.json2Remote access settings, or xopc tunnel secret set
Dev default3Only for non-production brokers (localhost, etc.)

The web UI masks saved secrets (••••••••••••); PATCH with masked sentinels leaves the stored value unchanged. Send null to clear.

Prefetch (optional)

bash
pnpm run electron:frpc:download   # current OS/arch → ~/.xopc/bin
node scripts/download-frpc-binaries.mjs --all   # all platforms (mirrors / CI)

Prefetch is not required; the first tunnel start downloads if the cache is missing.

Before the first start (and again when we bump the consent version), you must accept the security notice:

  • Config: tunnel.consent.version + tunnel.consent.acceptedAt
  • Current version: see CURRENT_TUNNEL_CONSENT_VERSION in src/tunnel/consent.ts
  • Web: confirmation modal on /settings/tunnel
  • CLI: interactive prompt, or xopc tunnel start --accept-risk / xopc tunnel consent

If the notice text changes, the version string is bumped and existing consent is invalidated until you re-accept.

On gateway load, invalid consent clears tunnel.enabled and tunnel.autoStart in config (persisted automatically).

Configuration flags

FieldMeaning
tunnel.enabledUser has turned remote access on (set on successful start, cleared on stop)
tunnel.autoStartStart tunnel when gateway listens (requires valid consent and enabled)
tunnel.consentRecord of accepting the security notice

Risks (summary)

  1. Anyone with your public URL or pairing QR may reach the gateway with your Bearer token.
  2. Traffic is proxied through broker / frps infrastructure.
  3. Stopping the tunnel does not instantly revoke all broker-side state; subdomain may remain reserved until expiry.

Recommendations

  • Use a strong gateway token and rotate if a URL or QR was exposed.
  • Prefer allowlist / pairing policies on channels where applicable.
  • Stop the tunnel when you do not need remote access.
  • Do not enable autoStart unless you accept exposure on every gateway launch.

API

  • POST /api/tunnel/consent — record acceptance (authenticated)
  • POST /api/tunnel/start — returns 403 + TUNNEL_CONSENT_REQUIRED if consent is missing or outdated
  • POST /api/tunnel/stop — body { "release": false } (default) keeps broker registration; release: true deregisters and clears tunnel.json
  • GET /api/tunnel/status — includes consentRequired, canAutoStart

Mutating tunnel endpoints are rate-limited per gateway token (12 calls / 5 minutes). Denied starts and consent/start/stop/release are written to logs with prefix TunnelAudit.

CLI

  • xopc tunnel stop — stop frpc, keep subdomain
  • xopc tunnel stop --release — deregister and clear saved URL (interactive confirm; --yes to skip)
  • xopc tunnel prefetch — download frpc only, no tunnel exposure
  • xopc tunnel secret set [secret] — save broker registration secret to config (--stdin for scripts)

Advanced

  • Override frpc binary: XOPC_FRPC_PATH
  • Offline / mirror: host frpc tarballs internally and point downloads at your mirror (see src/tunnel/frpc-binary.ts)
  • Extraction tries system tar, then a built-in Node parser (macOS BSD tar quirks, Windows without tar, minimal Linux images)

Transport TLS (broker-terminated)

Subdomain HTTPS is terminated at the broker with a wildcard certificate (*.frp.xopc.ai). The gateway runs frpc in HTTP mode directly to the gateway port — no per-gateway ACME or local TLS proxy.

Verify after cutover:

bash
TUNNEL_PUBLIC_URL=https://{sub}.frp.xopc.ai pnpm run tunnel:phase6:verify

Remote mobile API

The mobile app uses broker TLS + gateway Bearer token over https://{sub}.frp.xopc.ai/api/* (full path proxy on the broker).

Released under the MIT License.