The invariant novox/hq ADR 0001 records as unowned, and it was measurably false in HAL: a provision documented as never rotating minted a new password on every adoption and updated only the provider's row. Consumers on three nodes held dead credentials for two days while the mesh reported success. Nothing enumerated who held the old one. Three things make that impossible here. The holders are a set the mesh can name — each pair has its own credential, so rotating one consumer touches one role and the affected list is a query rather than an assumption. Both ends are pushed by this command rather than a later one, because leaving the sending to whoever remembered is the fault exactly. And it is all-or-nothing: if any affected machine cannot be resolved, nothing is sent and the old credential keeps working, which is a mesh that has not rotated rather than one that has half-rotated. The window is stated rather than hidden: a role's password changes on the provider and the file changes on the consumer, and they cannot be simultaneous. The provisioner now takes its superuser password from the file the mesh wrote, which is how the mesh delivers one. Passing it through the environment needed a person in the middle of the one path that exists so there is not one — and put a superuser password where `docker inspect` prints it.
examples
Things that run, kept here because a contract is easier to read as working code than as prose.
Nothing here is part of the control plane. The control plane decides and never touches a machine (README); everything in this directory runs on a machine and touches it. These are reference implementations of contracts the control plane defines, and a real one ships with the module that ships the software it configures.
postgres-provisioner |
the last step of a credential: reads what the mesh delivered and makes PostgreSQL accept it |
Running the provisioner
--watch reconciles now and again whenever what the mesh delivered changes. That is what lets it
be a module: an ordinary long-running service the host supervises, rather than something that has
to be invoked after every declaration by a timer or a unit wired to a file.
It polls rather than watching the filesystem, because the host writes atomically — the file is replaced, so a watch on the path stops seeing anything after the first replacement. A watcher that silently stops working is worse than a poll.
Credentials are compared by digest and never by content. This runs for as long as the machine is up, and a secret does not belong in a long-lived variable when a hash answers the same question.