A key that is present and unusable, and what the certificate work became
Issue 014: the node's serving key was stored in the host's own encoding, so every check that reads the file passed and no server could start. Same shape as 013 — two halves of one mechanism designed separately, each correct about its own half. Where a file exists so a third party can read it, the format is the interface.
This commit is contained in:
@@ -3,7 +3,9 @@ layer: to-be
|
||||
status: designed
|
||||
code:
|
||||
- mesh-control internal/catalogue/filtering.go
|
||||
- mesh-host internal/apply (the service that reflects it)
|
||||
- mesh-control internal/identity/authority.go
|
||||
- mesh-host internal/identity/serving.go
|
||||
- mesh-host internal/apply (the service that reflects a rule set)
|
||||
updated: 2026-08-31
|
||||
decisions:
|
||||
- 02-DECISIONS/0005-the-node-host.md
|
||||
@@ -315,7 +317,7 @@ something:
|
||||
| **flush the ruleset** when loading | that empties every table on the machine, the runtime's among them. Only the mesh's own table is replaced, and it is declared empty first so the replacement works on a machine loading one for the first time |
|
||||
| carry a **command to load itself** | the link may not carry an action ([ADR 0005](../../02-DECISIONS/0005-the-node-host.md)). A service is declared to reflect the file instead, so replacing it restarts what loads it — the shape that rule leaves, used here for the first time for its real purpose |
|
||||
|
||||
**And it is enforced, which is what separates this from `scope:`.** Proven on two real machines:
|
||||
**And it is enforced, which is what separates this from `scope:`.** Checked on two real machines:
|
||||
two ports opened, one declared, and from the other machine the declared one answers and the
|
||||
undeclared one does not — then the module is removed and the port closes with nobody editing a
|
||||
rule. *A rule set that is written but never loaded passes every check that reads the file, which
|
||||
@@ -348,6 +350,34 @@ fingerprint in its token ([ADR 0004](../../02-DECISIONS/0004-a-node-and-how-it-j
|
||||
so nothing needs the CA before membership. It certifies internal names afterwards, and that is
|
||||
all it does.
|
||||
|
||||
### What was built
|
||||
|
||||
*2026-08-31.*
|
||||
|
||||
**A node generates a fourth key**, and the reason is the one the other three already give: *a key
|
||||
used for two purposes is one rotation away from breaking the other.* The identity key would work
|
||||
for TLS and reusing it would mean rotating a node's identity every time its certificate is
|
||||
replaced. The private half never leaves the machine; the mesh is told the public half at
|
||||
enrolment.
|
||||
|
||||
**So there is no certificate request and nothing to seal.** The mesh signs a statement binding a
|
||||
public key to a name it alone assigns, which is the whole of what a certificate authority does.
|
||||
It issues rather than stores: the node's key does not change, so signing again produces an equally
|
||||
valid certificate and there is nothing to keep in step.
|
||||
|
||||
**A machine with no name inside the mesh is refused**, not given a certificate for nothing. A
|
||||
certificate for a name nothing resolves is a certificate nothing can check.
|
||||
|
||||
**And the key is stored in the format a server reads** — PKCS#8 PEM, not the host's own encoding.
|
||||
That is not an implementation detail of whoever writes the file: the file exists *because
|
||||
something else reads it*, so the format is the interface
|
||||
([04-ISSUES/014](../../04-ISSUES/014-a-key-that-is-present-and-unusable/00-report.md)).
|
||||
|
||||
*Checked by a real handshake between two machines: one serves on its internal name with the key it
|
||||
generated, the other verifies against the mesh's authority and nothing else. Every cheaper check
|
||||
passed while the server could not start — the key was present, the certificate was valid, and
|
||||
nothing read either the way a server would.*
|
||||
|
||||
## What this removes
|
||||
|
||||
The list is worth having in one place, because it is most of the argument:
|
||||
|
||||
Reference in New Issue
Block a user