From 27b2d3044175695ea8f881abb0149b31069f5a5a Mon Sep 17 00:00:00 2001 From: jochen Date: Sun, 4 Oct 2026 11:59:23 +0200 Subject: [PATCH] Research 027/03: ~/.ssh as one module's, scripts on every machine, the keyring, mail as events --- .../00-overview.md | 1 + .../03-the-accounts-own-tools.md | 128 ++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 01-RESEARCH/027-the-system-layer-as-modules/03-the-accounts-own-tools.md diff --git a/01-RESEARCH/027-the-system-layer-as-modules/00-overview.md b/01-RESEARCH/027-the-system-layer-as-modules/00-overview.md index aa64f27..024df41 100644 --- a/01-RESEARCH/027-the-system-layer-as-modules/00-overview.md +++ b/01-RESEARCH/027-the-system-layer-as-modules/00-overview.md @@ -51,4 +51,5 @@ matters on their own. - [01 — What the machines run](01-what-the-machines-run.md): evidence. - [02 — Candidates and questions](02-candidates-and-questions.md) +- [03 — The account's own tools](03-the-accounts-own-tools.md): `~/.ssh` as one module's, scripts on every machine, the keyring, mail as events - The predecessor's lessons, shared with research 026: [026/03](../026-the-graphical-session-as-modules/03-what-the-predecessor-taught.md) diff --git a/01-RESEARCH/027-the-system-layer-as-modules/03-the-accounts-own-tools.md b/01-RESEARCH/027-the-system-layer-as-modules/03-the-accounts-own-tools.md new file mode 100644 index 0000000..69f0f4d --- /dev/null +++ b/01-RESEARCH/027-the-system-layer-as-modules/03-the-accounts-own-tools.md @@ -0,0 +1,128 @@ +# 03 — The account's own tools: ssh, scripts, mail + +Three further directions from the operator on 2026-10-04. Each is account-level, like the shell +([to-be 41](../../03-DESIGN/01-to-be/41-the-shell-and-the-accounts-environment.md)). + +## `~/.ssh` is one module's + +*"A module owns `~/.ssh`, so it is its responsibility that every folder is set up consistently and +correctly."* + +**Measured:** + +- The catalogue's `ssh-client` module owns the directory (mode 0700) and one region of + `~/.ssh/config`: a `Host` block per machine of the mesh. It owns nothing else. +- On one workstation, a predecessor's header, `Include` and hand-written host block sat **above** the + mesh's region. ssh takes the first match, so the predecessor's entries were the ones in force, for + the same machines. Removed on 2026-10-04. +- On the control machine, two keys of a retired CI system were still in the operator's + `authorized_keys`, able to log in as the operator. Removed the same day. +- Permissions differ by file and by machine. Backups of the configuration lie beside it. + +**Starting position:** `ssh-client` becomes the holder of everything under `~/.ssh`, classified as +ADR 0182 asks: + +| path | class | how | +|---|---|---| +| `~/.ssh/`, its mode, every file's mode | owned | the directory resource, plus a check verb that reports a file with the wrong mode | +| `~/.ssh/config` | written into, the mesh's block **at the start** | the mesh's hosts win; the operator's lines after it are kept; an `Include config.d/*` line in the block | +| `~/.ssh/config.d/` | owned by the contributing module | ssh's own drop-in: a work module adds its forge's host there (research 026 C1) | +| `~/.ssh/authorized_keys` | written into, the mesh's block | the operator's keys as the mesh records them, and nothing a retired system left. The operator's own lines are kept below the block | +| `~/.ssh/known_hosts` | written into, the mesh's block | every mesh machine's host key, so the first connection never asks | +| private keys | found | never read and never written by the mesh; a key the mesh should hand out comes from the vault, through the module's own process (ADR 0182, third class) | + +The sshd module is the other half: the machine's side. It is already in the catalogue. + +## Scripts on every machine, shared and machine-specific + +*"All nodes should get some custom scripts, both node-specific and mesh-specific (shared)."* + +**Measured:** the operator's script folder holds 64 entries plus 33 in its `bin/`. It is under no +version control, and exists only where it was copied. It mixes three kinds: + +1. scripts belonging to a module (the desktop's watchers, lock, menus; a laptop model's brightness); +2. the operator's own tools; +3. installers that modules have replaced. + +**Starting position:** + +- **The operator's scripts live in a repository of their own,** registered as any application is + ([ADR 0015](../../02-DECISIONS/0015-applications-live-in-their-own-repository.md)), built as archives, + unpacked into a directory the module owns under the home. `bin/` goes on `PATH` through an + environment contribution ([ADR 0203](../../02-DECISIONS/0203-the-accounts-environment-is-one-modules-and-every-module-contributes-to-it.md)), + and small functions go into the shell through a `shell` contribution + ([ADR 0204](../../02-DECISIONS/0204-a-module-contributes-shell-code-to-the-login-shell-in-named-slots.md)). +- **"Machine-specific" is said by assignment, never by naming a machine** + ([ADR 0112](../../02-DECISIONS/0112-a-module-definition-names-no-node-mesh-or-path.md)). One repository + holds several modules: + - `scripts` (shared, on every machine); + - `scripts-workstation`; + - `scripts-media`; + - and so on, each assigned where it applies. + + A script that belongs to a piece of software or hardware moves into that module instead. A flavor + inside one module is what [research 026/03](../026-the-graphical-session-as-modules/03-what-the-predecessor-taught.md) + says not to repeat. +- **A script can also be a tool.** A script with a one-line description is served by the node's + runtime, so it can be called through the mesh on any machine that has it. +- A script that needs a secret gets it through question 2's mechanism, never from a file of + environment secrets. + +## The keyring + +*"A keyring is also a good thing to create a module for."* + +**Measured on the two workstations, which both run GNOME Keyring:** + +- **On one, the keyring unlocks at login.** The login manager's PAM service includes `login`, which + carries `pam_gnome_keyring`. +- **On the other, it does not.** The PAM line is only in the screensaver's service, so at session + start the window manager runs a script that asks for the password a second time and unlocks the + keyring with it. +- **On both, the session's start script starts the daemon again** with the ssh and gpg components, + and exports the ssh agent's socket. The keyring's current release serves the ssh agent through a + separate per-user socket unit instead. + +**Starting position:** a `gnome-keyring` module that holds a node seat, `node-secret-service` (the +holder of the desktop's secret service; a password manager could hold it instead). It declares: + +- the package; +- its lines in the login manager's PAM file, written into, never over (ADR 0102), so login unlocks it + on every machine; +- the ssh agent's user socket, once user-scoped units ship; +- the agent's socket path as an environment contribution, which needs a machine fact for the + account's runtime directory. ADR 0203 forbids `$` in values, so `$XDG_RUNTIME_DIR` cannot be + written in one. + +The second unlock prompt and the second daemon start go away. + +## Mail as events + +*"Ideally a mail consumer with all my mail accounts configured, so my mail is recorded in the bus."* + +**Measured:** + +- The predecessor polled one work mailbox every minute. It **read an access token out of the mail + client's process memory**, called a mail API with it, and raised a desktop notification per unread + message. It worked only while the mail client ran, and stopped silently when the predecessor's units + were retired. +- Two further predecessor modules served mail tools, for one provider and for IMAP. +- The mesh runs a mail server of its own for its domains. + +**Not decided here; it needs an effort of its own.** The questions it would have to answer: + +- **Accounts and how each authenticates:** + - IMAP with an app password; + - a provider's OAuth with a registered application; + - the mesh's own mail server, which can publish delivery itself. + + An employer's tenant may forbid registering an application at all. +- **What the bus records:** + - headers and a summary as events; + - bodies and attachments in an object store the event points at; + - retention, since mail is the most personal data the mesh would hold. +- **What consumes it:** a notifier bridge to the desktop (the predecessor's notifications), search, + an agent's context. +- **Where it runs:** one long-running module, not per machine (ADR 0198). + +The obvious first step is the mail server the mesh already runs.