Reconcile: adopt initialization's consolidated HQ as canonical, re-home this session's new work #24
@@ -173,11 +173,55 @@ address of its database on another, as a file, and reaches it by a name the mesh
|
|||||||
stated absence looks like a boundary, and somebody wiring this up should not spend an afternoon
|
stated absence looks like a boundary, and somebody wiring this up should not spend an afternoon
|
||||||
looking for a password that was never going to be there.
|
looking for a password that was never going to be there.
|
||||||
|
|
||||||
**What remains is the secret itself**, and it is the larger half: it must exist, be stored, reach
|
### And the secret, which is delivered without ever being held
|
||||||
one node and not the others, and rotate with every holder informed — which is
|
|
||||||
[the invariant set](0001-mesh-brokers-nodes-host-agents-think.md) that was found violated three
|
*Written 2026-08-30, after looking at how the existing mesh does it. The design here is a reaction
|
||||||
ways at once, and the reason it is not something to add in passing. What is built is the shape it
|
to a measurement, not a preference.*
|
||||||
will arrive in.
|
|
||||||
|
**The obvious arrangement is a credentials column, encrypted at rest.** It exists, and its own
|
||||||
|
tooling records what it bought:
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| the tool for finding a secret matches **by value**, not by name | because one password is in the provisions table, the environment table, each node's environment file in plain text, and **inside every connection string composed from it** — copies its documentation calls *"often the only copies actually in use"* |
|
||||||
|
| a query against the encrypted column **returns zero rows and proves nothing** | so auditing moved to the decrypted copies on the machines |
|
||||||
|
|
||||||
|
**Two faults, and encryption at rest addresses neither.** The control plane can read what it
|
||||||
|
stores, so a copy of its database is a copy of every credential in the mesh. And one secret has
|
||||||
|
many homes with nothing tracking them — **composition is what mints the untracked ones**, because
|
||||||
|
building a connection string centrally creates a new secret-bearing value no rotation path knows
|
||||||
|
about.
|
||||||
|
|
||||||
|
**So the value is sealed to the node that will use it before it is stored.** With a key that node
|
||||||
|
generated and whose private half the mesh has never seen — a third key beside the identity and the
|
||||||
|
overlay, for the same reason those are two rather than one. What is stored is unusable by whoever
|
||||||
|
holds it, the mesh included, and the broker relays a blob it cannot read. This is what makes
|
||||||
|
[ADR 0004](0004-a-node-and-how-it-joins.md)'s *compromise of a node is compromise of that node*
|
||||||
|
true of secrets rather than true of identity and quietly false of everything that matters.
|
||||||
|
|
||||||
|
**And nothing is composed centrally.** A connection string is assembled on the machine that needs
|
||||||
|
one, if at all. The mesh delivers parts.
|
||||||
|
|
||||||
|
**What it costs, stated because it is real:** the mesh cannot audit by value. That is the right
|
||||||
|
trade rather than an oversight — a query over an encrypted column could not either, so the audit
|
||||||
|
was never real. What *is* answerable is which node holds what, which is the question rotation
|
||||||
|
actually asks.
|
||||||
|
|
||||||
|
**A consequence that shapes the mechanism.** The mesh discarded the plaintext, so it cannot
|
||||||
|
compose a file containing it. The credential is therefore **its own file**, holding the value and
|
||||||
|
nothing else, beside the readable one. That is better than the alternative it was forced into:
|
||||||
|
the readable half stays readable in the declaration, and the secret half changes only when the
|
||||||
|
secret does, so a service reloading on it reloads for a real reason.
|
||||||
|
|
||||||
|
**Rotation is generating a new one**, because reading the old one back is not possible. Both ends
|
||||||
|
are re-sealed and reach their machines in the same push — which removes the window where half the
|
||||||
|
mesh holds a dead credential, the failure
|
||||||
|
[recorded in ADR 0001](0001-mesh-brokers-nodes-host-agents-think.md) as consumers on three nodes
|
||||||
|
holding one for two days.
|
||||||
|
|
||||||
|
**What remains is a provisioner** — something that creates the database user the credential is
|
||||||
|
for. The mesh now generates the secret, tells the provider to create it and the consumer to use
|
||||||
|
it; nothing yet acts on the telling.
|
||||||
|
|
||||||
**One check that only became possible now.** Two machines wired together across no private network
|
**One check that only became possible now.** Two machines wired together across no private network
|
||||||
is a mesh that reports itself configured and does not work, and the failure surfaces as a
|
is a mesh that reports itself configured and does not work, and the failure surfaces as a
|
||||||
|
|||||||
Reference in New Issue
Block a user