novox/hq ADR 0035: one implementation, several surfaces, and a surface holds no decisions. The act of assigning — including that an assignment which does not resolve is kept and still refused — moved into acts.go, and the command line now calls it too. Two surfaces, one refusal, in the same words. It will not run without --issuer, and refuses at start rather than per request so it is found by whoever ran it rather than by whoever finds it. There is no flag that removes the check. The authenticator is honest about what it is: no token can be verified until an identity provider exists, because that is a module and none is running, so every request is refused and told that the command line still works. A surface that functioned without authentication would be one somebody left running — and the board this stands behind is published on a public name. Four refusals, four tests. The last one first asserted "not 200", which passed because a request with no database fails at the store anyway — it proved nothing about whether the input was checked. It now asserts the specific refusal, and bites when the check is removed.
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.