ConnectOnionAll Posts

Design Journal · August 15, 2026 · ConnectOnion 1.6.8

The Owner Needs a Door

A careful default must keep strangers out and still give the owner a private way back in.

co ai was secure on a fresh install. It was also unusable. The careful policy correctly admitted no stranger, but the shortest setup path had never created the private invite its owner needed to connect.

The decision

Create one private recovery path automatically; disclose its credential only when the owner asks.

The missing door

Project scaffolding already minted a unique CO_INVITE_CODE. But the documented shortest path—install, then run co ai—hosts the global identity directly and never passes through co init or co create. The host therefore had no onboarding method to advertise.

Alternatives we rejected

Print a new code at startup

Convenient, but every terminal capture, CI log, screen share, and support paste becomes a credential leak. Partially masking it reveals secret material without leaving enough to use.

Use a fixed fallback

A universal fallback is just the old public password under a new name. It makes every fresh installation share one access-control secret.

One code, minted once

The server path now ensures ~/.co/keys.env contains one owner invite. A process or project value wins, an existing global value is reused, and only a truly empty setup mints a new one. A cross-process lock protects simultaneous cold starts, and the file is owner-readable on POSIX.

co ai
# Owner invite created. Run co keys --reveal when onboarding your client.

co keys            # confirms a masked invite exists
co keys --reveal   # deliberate private disclosure

The tradeoff

Automatic creation means a secret now exists even before the owner explicitly asks for one. Keeping it in the owner-only credential file and out of normal output makes that tradeoff smaller than either locking the owner out or teaching logs the credential.

Evidence

Regression tests start from an empty home, exercise the real careful rule with the minted invite, reject an unrelated value, preserve an existing invite across restart, serialize two first starts, and confirm plain co keys never reveals it. The 1.6.8 Linux and native-Windows release matrices passed before publication.

What would make us revisit this

If onboarding moves to a hardware-backed or out-of-band owner proof, a stored invite may no longer be the best recovery primitive. Until then, the invariant stays simple: deny the wrong person and preserve a private path for the right one.

See the co ai guide for the user flow and A Page Should Not Become a Wall for the other boundary repaired in 1.6.8.

Star us on GitHub

If ConnectOnion saves you time, a ⭐ goes a long way — and earns you a coffee chat with our founder.