08-connectivity keeps two authorities apart on purpose: a public one for names the outside world reaches, and the mesh's own for names only the mesh knows. Nothing implemented the second, so anything between machines was plaintext or trust-on-first-use — which the design refuses everywhere else. A node now generates a fourth key at enrolment and reports the public half. A fourth, because a key used for two purposes is one rotation away from breaking the other: the identity key signs messages to the mesh and would do for TLS, and reusing it would mean rotating a node's identity every time its certificate is replaced. **Nothing secret travels and nothing is sealed.** A certificate authority says "this name belongs to the holder of this key", so the mesh signs a public half it cannot use, and the certificate it issues is public. A module asks for one and is given the certificate and, if it wants, the mesh's own — the private key is a path to a file the machine already has, the same arrangement the private network's key uses. Asserted by verifying rather than inspecting, because a certificate that parses and does not chain fails at the moment something connects: - what the mesh issues verifies against the mesh, for the name asked for - the name is in the subject alternative names, since a certificate carrying it only in the common name is refused by every modern client - it certifies the key the node generated and no other - another mesh's certificate does not verify, which is the whole point of two authorities being separate - the authority cannot sign another authority — one that could is one that can be delegated without anybody deciding to - two control planes starting together agree on one authority, or a mesh has certificates half its machines refuse Certificates last ten years, which is a choice: a short life needs something to renew it, and a renewal that fails silently is a mesh that stops trusting itself on a date nobody wrote down. What makes one replaceable is that the mesh reissues on demand, not that it expires.
33 lines
1.6 KiB
SQL
33 lines
1.6 KiB
SQL
-- The authority that certifies names inside the mesh.
|
|
--
|
|
-- novox/hq 08-connectivity keeps two authorities apart on purpose: a public one issues for names
|
|
-- the outside world reaches, and this one issues for names only the mesh knows. Collapsing them
|
|
-- would mean a public authority being asked to certify a name it cannot verify, and a mesh
|
|
-- authority being trusted by things outside it.
|
|
--
|
|
-- **It is not a bootstrap concern.** A joining node verifies the control plane against the
|
|
-- fingerprint in its token, so nothing needs this before membership. It certifies internal names
|
|
-- afterwards, and that is all it does.
|
|
|
|
create table authority (
|
|
-- One row, like the signing key beside it. Two authorities and nothing says which certificate
|
|
-- to believe.
|
|
singleton boolean primary key default true check (singleton),
|
|
|
|
certificate text not null,
|
|
-- The private half. Held here because signing is what this context is for -- the same
|
|
-- reasoning as the signing key, which is also held and also never leaves.
|
|
private text not null,
|
|
|
|
made_at timestamptz not null default now()
|
|
);
|
|
|
|
-- What a node serves TLS with, and what was issued for it.
|
|
--
|
|
-- The public half only. The node generated the pair and keeps the private one, so a copy of this
|
|
-- table certifies nothing and impersonates nobody -- which is the same property the node keys
|
|
-- table has, for the same reason.
|
|
alter table node_key add column serving_key text;
|
|
alter table node_key add column certificate text;
|
|
alter table node_key add column certified_at timestamptz;
|