---
title: "Security and Privacy"
description: "Understand Cloud Link trust boundaries, what the control plane stores, how device and browser credentials work, and the security limits you should know."
canonical: "https://opencodecloud.link/docs/security/"
lastUpdated: "2026-10-19"
---
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.

## Trust boundaries

| 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.

## What the control plane stores

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.

## Device credentials

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.

## Pairing security

- 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.

## Browser credential

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.

## Exposed services

- 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

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.

## Known limitations

- 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.

## Practical guidance

- 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](/docs/subscription/) and the
[Privacy Policy](/privacy-policy/) for related terms.