The mechanics — receipts
1 min read · 284 words
A few decisions deserve their own lines, because a reader should be able to take them and use them.
Three layers, none sufficient alone. Network perimeter (default-deny grants), identity (the wire), and application grants (per-item tables) — each covers what the other two cannot. A grant at the network layer cannot tell one book from another; a grant at the application layer cannot stop a device from reaching the host. Together they hold.
Union semantics. Tailscale's grants can only add access. This looks like a weakness until it turns the security model into arithmetic: isolation comes from the absence of grants, and absence is exactly what the deny-tests prove. You cannot accidentally carve a hole; you can only fail to close one, and the tests catch that.
The allow-all footgun. A fresh tailnet, before any policy file exists, allows everything. We ship a policy file at first boot. An appliance handed to a non-technical person must never spend one second in the default state.
The pull doctrine. Members pull their credentials from the node; the node never holds a way into a member's machine. Enforced in the policy by a deny-test. The direction credentials travel decides the shape of the network.
Capability tokens for things that travel. A book can be handed to a phone or a Telegram chat by a link that is hashed at rest, expires by default, and is revocable in one stroke. The token names one item and nothing else.
The lineage. The per-item grant did not appear from nothing. It is the same idea as a legacy UserBookEntitlement table that once carried a LOANED_TO_COMMUNITY status, reborn on rails that actually enforce it. Sovereignty is old ideas finally given teeth.
