Security
We introduce. We never listen.
The control plane exists to bring your browser and your daemon into the same room. The moment they shake hands, it goes deaf. The distinction we build to: the server cannot read your terminal — not “we don’t look,” but “we can’t.”
“The only parties that handle your terminal are the daemon on your host and the browser in your hand. The server introduces them; it never sees the conversation.”
— the governing principle, verbatim from the threat model
How the server stays deaf
End-to-end encrypted, browser to daemon.
Direct channels
Terminal input, output, and scrollback ride encrypted WebRTC DataChannels negotiated directly between the two endpoints. The keys live at the endpoints; the server holds none of them.
Signaling only
The control plane carries auth, lifecycle, and the introduction handshake. There is no server code path for terminal content, no transcript store, nothing to hand over.
Ciphertext relay, as a fallback
A relay is used only when NAT leaves no direct path. It then forwards opaque ciphertext it can’t decrypt — reachability without disclosure.
Outbound-only hosts
The daemon dials out and holds the line. No inbound ports, no exposed SSH, no tailnet. Nothing reaches in; the daemon only reaches out.
The honest ledger
What it can’t see — and what it still does.
A trust document that hides its weaknesses is worthless. So here is the whole ledger, not the flattering half.
Cannot see
- Your terminal input, output, and scrollback
- The contents of any file on your hosts
- What your agents are actually doing
- Your API keys or agent logins — it never has them
Still sees (the metadata)
- Which hosts you own and when they’re online
- That an agent stirred — never what it said
- Connection timing and approximate volume
- Self-host the whole stack if even this is too much
Deaf, and blind to tampering
Verify the fingerprint. Refuse the impostor.
Every connection is signed by endpoint identity keys and pinned on first contact. A hostile relay that tries to substitute a key to wiretap the handshake is caught: the daemon prints its fingerprint, you compare it once, and a changed fingerprint is refused, loudly. It’s the tailnet-lock model — trust the endpoints, not the introducer.
$ spawnd status
host dream
fingerprint 4f:9a:c3:e1:0b:77:d2:5c…
signed offer verified against local pin ✓
this session is yours alone.
The scarier it sounds, the safer it is.
A daemon that dials out and answers to one master sounds ominous — until you notice who the master is. You installed it. You approved it against a key you can see. And you can inspect everything it can’t: the source is open, and the threat model names our own servers as the adversary. Don’t take our word for it — read it.
