What the relay can see
A plain accounting of what relay.cua.ai (or any self-hosted cua-relay) can and cannot see, and what we have done and are still doing about it.
A plain accounting of what relay.cua.ai (or any self-hosted cua-relay) can and cannot see, and what we have done and are still doing about it.
relay.cua.ai (and any self-hosted cua-relay) is a trusted, TLS-terminating
proxy, not a blind relay. This page says plainly what that means, kept
current as the relay changes. If anything here reads as a surprise, it is a
bug in this page: tell us.
/files transfers) to route
and authorize it. It can read the plaintext of anything it proxies while
the request is in flight: shell output, file contents, the desktop media
stream, keystrokes and clipboard data sent as input, and, unless sealed
(below), Keyvault passwords and teleport session bundles.libs/cua-spacesd/crates/cua-relay/README.md in the cua repository)
for the exact claims and how they are enforced in code.| Path | Relay sees plaintext? | |
|---|---|---|
| gRPC (shell, files, input) | Parsed and forwarded | Yes |
| Desktop media stream | Parsed and forwarded (TCP over the relay; QUIC only on a direct/LAN path) | Yes |
/files transfers | Parsed and forwarded | Yes |
| Env / account tokens | Stripped and replaced (account mode); forwarded unmodified, not stored (static mode) | In transit only (static mode); not at all (account mode) |
| Keyvault site-login password | browser_type call argument | Gated: refused over a relay: Space by default; sending anyway needs your explicit, per-sign-in acknowledgement (no end-to-end sealing for this path yet; see below) |
| Teleport session bundle (cookies, Safe Storage keys) | TeleportService.ImportSession | Sealed once the Space's guest key is pinned (every image built from this point on); gated otherwise: refused unless you explicitly acknowledge the risk for that one delivery |
We seal teleport secrets end to end to the destination machine's own key, so
the relay forwards only ciphertext for a sealed delivery. The construction:
an ephemeral X25519 key per delivery, HKDF-SHA256, XChaCha20Poly1305, bound
to the Space id, a purpose string and a timestamp, with replay rejection
(cua-machine-seal; no hand-rolled crypto, every primitive is a vetted
RustCrypto / dalek crate). A guest's spacesd generates its own keypair on
first start (0600 on disk) and reports the public half through its
capabilities; the host pins it on first use (trust-on-first-use) and seals
every subsequent teleport delivery to it.
Current state, honestly: teleport's sealing and the gate are both live.
A Space whose image was built before this shipped reports no guest key, so
the teleport ImportSession path (which the Keyvault broker's combined
prompt also uses for cookies and session data) refuses to send over a
relay: Space from such an image unless you explicitly acknowledge the
risk for that one delivery -- republishing the guest image is what makes
the refusal go away, by making the delivery sealed instead. The
Keyvault site-login password path (typed directly into a page via
browser_type) is gated the same way, but not yet sealed: a saved
password still crosses the relay as a plain request argument when you
acknowledge the risk, since there is no practical way yet to seal a single
driver-call argument the way a whole bundle upload is sealed. Treat an
acknowledged site-login sign-in into a relay: Space the same as you
would treat typing that password into any other network request that
crosses a proxy you do not control, until this page says otherwise.
Local and direct Spaces are unaffected either way: no relay is in the path, so there is nothing to seal against.
GET /v1/audit?format=jsonl for export to your own
SIEM or backup.See SECURITY.md for
how to report a vulnerability privately, our response targets, and our safe
harbor for good-faith security research.