From a0283374908760adb5023c03686da970506cc81f Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 31 Aug 2026 20:23:42 +0200 Subject: [PATCH] The local account owns the mesh; a surface delegates to a module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Answers what 0031 left open, and a question it did not ask — who owns the mesh at all. There was no answer, and the absence was invisible because every operation so far has been run by the person sitting at the machine, so nothing had to say whether that was the design or the circumstance. The account that installed the host owns the mesh on that node. No user model, no roles, nothing to administer. It follows from 0004 rather than adding to it: there is no authorisation between nodes because every node is the operator's own, so a user model inside that boundary would guard nothing — anyone it could stop could read the node's key off the disk. The board is different, and the difference is the network. A surface reachable by a browser has to know who is asking, because those people are not by construction people with a shell on the machine. So it delegates to an OAuth provider, which is a module. That does not make identity substrate. A surface delegating authentication is not the control plane delegating it: the control plane runs, applies declarations and reaches nodes with no identity provider in existence. Only the board needs one. Records the cost plainly: anybody with a shell on a node has full authority there, and there is no way to give somebody authority over one node without giving them a login on it. --- .../0032-the-local-account-owns-the-mesh.md | 78 +++++++++++++++++++ 02-DECISIONS/README.md | 1 + 2 files changed, 79 insertions(+) create mode 100644 02-DECISIONS/0032-the-local-account-owns-the-mesh.md diff --git a/02-DECISIONS/0032-the-local-account-owns-the-mesh.md b/02-DECISIONS/0032-the-local-account-owns-the-mesh.md new file mode 100644 index 0000000..c288478 --- /dev/null +++ b/02-DECISIONS/0032-the-local-account-owns-the-mesh.md @@ -0,0 +1,78 @@ +--- +topic: how we work +status: accepted +date: 2026-08-31 +deciders: jochen +reconstructed: false +extends: 02-DECISIONS/0031-the-control-plane-authenticates-nobody.md +--- + +# 32. The local account owns the mesh; a surface delegates to a module + +## Context + +[ADR 0031](0031-the-control-plane-authenticates-nobody.md) settled that the control plane +authenticates nobody, and deliberately left one thing open: **how a person signing in to a mesh +surface is authenticated.** This answers it, and answers a question 0031 did not ask — *who owns +the mesh at all.* + +**There was no answer, and the absence was invisible** because every operation so far has been run +by the person sitting at the machine. Nothing had to say whether that was the design or the +circumstance. + +## Decision + +**The account that installed the host owns the mesh on that node.** Authority is a local login, +and there is nothing else to hold. + +**No mesh user model.** No accounts, no roles, no grants, nothing to administer. A person with a +shell on a node can do anything the mesh can do there, because that is already true and pretending +otherwise would be a boundary that does not exist. + +**This follows from what was already decided rather than adding to it.** +[ADR 0004](0004-a-node-and-how-it-joins.md) says there is no authorisation between nodes — every +node is the operator's own, so a message from one is a message from them, and *the mesh boundary +is therefore the security boundary*. A user model inside that boundary would guard nothing: anyone +who could be stopped by it could equally read the node's key off the disk. + +**The board is different, and the difference is the network.** A surface reachable by a browser +has to know who is asking, because the people reaching it are not, by construction, people with a +shell on the machine. **So the board delegates to an OAuth provider** — which is a module. + +## What this does not change + +**The identity provider is still not substrate** (ADR 0031). A *surface* delegating +authentication is not *the control plane* delegating it. The control plane runs, applies +declarations and reaches nodes with no identity provider in existence; only the board needs one, +and only to decide whose browser it is talking to. + +The test is unchanged and still answers no: *does the control plane need it in order to run?* + +## Consequences + +**The board depends on a module, and says so.** An ordinary edge in the graph, which means the +board cannot come up before the provider it authenticates against — stated as a dependency rather +than discovered as an outage. + +**Moving the identity provider takes the board with it.** During that module's own conversion the +board is unavailable, and that is acceptable: it is a surface, nothing depends on it, and a brief +interruption is the trade already accepted everywhere else. Nothing that keeps a service serving +goes through it. + +**Anyone with a shell on a node has full authority there.** Written down rather than left implied, +because it is the sentence that decides who gets an account on a machine. The protection is the +machine's own login, and the overlay that keeps the machine unreachable from outside +([ADR 0007](0007-connectivity.md)). + +**A node cannot be operated by somebody without a login on it.** Deliberate, and the cost of +having no user model: there is no way to give a person authority over one node without giving them +a shell there. If that is ever wanted, it is a new decision and not a gap in this one. + +## References + +- [ADR 0031](0031-the-control-plane-authenticates-nobody.md) — the control plane authenticates + nobody; this answers what it left open +- [ADR 0004](0004-a-node-and-how-it-joins.md) — no authorisation between nodes, and why the mesh + boundary is the security boundary +- [`03-DESIGN/01-to-be/11-a-board.md`](../03-DESIGN/01-to-be/11-a-board.md) — the surface this is + about diff --git a/02-DECISIONS/README.md b/02-DECISIONS/README.md index 8077008..e2c5a47 100644 --- a/02-DECISIONS/README.md +++ b/02-DECISIONS/README.md @@ -127,5 +127,6 @@ python3 00-META/checks/index.py fail if stale - **0022** — [The constitution absorbs what is already enforced](0022-the-constitution-absorbs-what-is-enforced.md) - **0023** — [The approval is the checkpoint, not the second pair of hands](0023-approval-is-the-checkpoint.md) - **0025** — [The design record is read where it is written, never copied to be found](0025-the-design-record-is-read-not-copied.md) +- **0032** — [The local account owns the mesh; a surface delegates to a module](0032-the-local-account-owns-the-mesh.md)