Skip to content

Security and Privacy

Cloud Link is designed so the control plane establishes the connection and then gets out of the way. This page explains the practical security model.

Path Protection
Phone → Cloudflare → connector TLS at the Cloudflare edge; signed device credential at the connector
Browser → Cloudflare → connector TLS at the edge; connector-generated browser credential
Connector → control plane HTTPS during pairing and management
Connector → OpenCode Loopback only; managed OpenCode uses an OS-random password
Connector → exposed services Loopback targets only; private by default

Cloudflare terminates TLS at its edge. There is no separate application-layer end-to-end encryption between the phone and the machine. Cloudflare can see plaintext while proxying the connection, as it can for any tunneled HTTPS site.

The control plane stores connection metadata needed to establish access:

  • account and subscription identifiers;
  • machine names and opaque installation identifiers;
  • tunnel hostnames and tunnel metadata;
  • pairing records and their status;
  • timestamps and operational records.

It does not receive or store prompts, responses, source code, terminal output, file contents, or model provider credentials. OpenCode traffic does not pass through the control plane.

After approval, the control plane issues a signed, machine-scoped credential to the phone. The connector pins the signing public key and verifies the credential locally.

  • The credential carries a device identity, machine identity, issue time, and expiry.
  • It is presented as HTTP Basic authentication, matching the mobile app’s connection model.
  • The control plane stores no per-device secret.
  • Credentials cannot outlive the verified subscription paid-through time.

Deleting the machine retires its tunnel and DNS record. Per-device revocation is not implemented, so machine deletion and credential expiry are the supported revocation paths.

  • A QR code is single-use, expires after five minutes, and is stored only as a hash.
  • The connector generates a per-pairing secret that never appears in the QR.
  • The machine operator sees the claiming device’s name and must approve it.
  • The tunnel token is withheld until approval.
  • A denied claim is retired, and a new code must be generated.
  • Replayed claims are rejected after the first successful consumption.

A leaked screenshot of a QR code is not enough to reach your machine without approval on the machine.

Remote browsers use a separate credential generated by the connector:

  • username browser;
  • a random 64-hex-character password;
  • stored in the native credential store or a protected file;
  • never sent to the control plane;
  • regenerable from the tray.

Regenerating the password invalidates existing browser logins. It does not affect the mobile app’s device credential.

Local OpenCode windows and local browsers use a short-lived, single-use pairing link against the loopback server instead of the remote browser credential.

  • Targets must be loopback addresses on unprivileged ports.
  • Hostnames, private network ranges, link-local addresses, and cloud metadata addresses are rejected.
  • New services start disabled and private.
  • Public access is an explicit per-service choice.
  • Each service is served on a separate origin from OpenCode.
  • Service management through /_cloudlink accepts only a signed device credential; the browser credential and public access are rejected.

Public and private services can share a port. Because they share an origin, a public page may attempt requests to private paths using the owner’s cached credentials. Mark a service public only when its content is trusted.

Keep awake is local-only. It reads host activity and holds a native idle-sleep assertion. No activity data leaves the machine, and the setting cannot be changed through the tunnel.

  • No per-device revocation. Delete the machine to retire access.
  • No application-layer end-to-end encryption against Cloudflare.
  • The Windows installer is currently unsigned.
  • Ticket-only mobile terminal WebSockets are rejected; Basic-authenticated WebSockets are required.
  • Remote termination after expiry can take up to the scheduled cleanup interval plus Cloudflare API propagation.
  • Local credential errors fail closed; macOS and Windows do not fall back to plaintext secrets.
  • Protect your store account and approve pairing only on a machine you control.
  • Treat QR codes, pairing links, public URLs, and browser passwords as secrets.
  • Regenerate the browser password after using an untrusted browser.
  • Delete machines you no longer use.
  • Review exposed services and make them public only when necessary.
  • Report suspected compromise by rotating browser access and deleting the affected machine.

See Subscription and billing and the Privacy Policy for related terms.

OpenCode Cloud Link is an independent project. It is not built by the OpenCode team and is not affiliated with them in any way. See thePrivacy Policy andTerms & Conditions.