Research: steward orders prior art (nix-daemon, Postfix pickup, Salt, AWX, deploy-rs, break-glass, two-person rule)
Serves eureka-body follow-up eureka-root-idunn-orders under ruling eureka-root-idunn-orders-break-glass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
024f2d7a09
commit
ecb2ae0995
1 changed files with 130 additions and 0 deletions
130
docs/research/steward-orders-prior-art.md
Normal file
130
docs/research/steward-orders-prior-art.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# Steward orders prior art: privileged agents, break-glass, two-person rule
|
||||
|
||||
Serves Eureka campaign `eureka-body`, follow-up `eureka-root-idunn-orders`, under
|
||||
ruling `eureka-root-idunn-orders-break-glass` (operator 2026-10-31: Eureka issues
|
||||
typed orders to Idunn, run as root and posted to #operator, plus an announced,
|
||||
brakeable break-glass order). Imagination pass, session eureka-self-2026-10-31.
|
||||
|
||||
Written from recall of the systems' documentation, not re-fetched on
|
||||
2026-10-31; each claim names where to check it. Facts first, then what each one
|
||||
says about this design.
|
||||
|
||||
## 1. Privileged agents that take requests from less privileged callers
|
||||
|
||||
### nix-daemon (closest shape)
|
||||
|
||||
- Unprivileged users never run as root: the Nix client talks to `nix-daemon`
|
||||
over a Unix socket (`/nix/var/nix/daemon-socket/socket`), and the daemon reads
|
||||
the caller's uid from the socket's peer credentials. `nix.conf`
|
||||
`allowed-users` says who may connect at all; `trusted-users` says who may
|
||||
pass privileged settings. (nix.conf manual, "allowed-users",
|
||||
"trusted-users".)
|
||||
- The daemon accepts a closed set of typed operations (the worker protocol),
|
||||
not shell strings.
|
||||
- Lesson: a local Unix socket plus `SO_PEERCRED` is the established way for a
|
||||
root agent to know which local principal is asking. The principal is derived
|
||||
from the kernel, never declared by the caller.
|
||||
|
||||
### Postfix maildrop and pickup
|
||||
|
||||
- Unprivileged `sendmail` writes into the `maildrop` queue through the setgid
|
||||
`postdrop` helper; the privileged `pickup` daemon reads each file, checks it,
|
||||
and copies it into its own queue before anything acts on it. (Postfix
|
||||
architecture overview, `pickup(8)`, `postdrop(1)`.)
|
||||
- Lesson: the submitter's inbox is not the record. The privileged side copies
|
||||
the request into a store only it can write, and only that copy is acted on.
|
||||
|
||||
### SaltStack
|
||||
|
||||
- The master publishes jobs to minions that run as root; each job gets a job
|
||||
id (jid) from the master, not from the caller, and returns are kept in the
|
||||
job cache (`salt-run jobs.lookup_jid`). (Salt docs, "Job management".)
|
||||
- `publisher_acl` and external auth (`external_auth`) grant a user named
|
||||
functions only, for example `pkg.install` and `service.restart`, optionally
|
||||
with argument patterns. (Salt docs, "Publisher ACL system", "External
|
||||
Authentication System".)
|
||||
- CVE-2020-11651 and CVE-2020-11652: the master's request server exposed
|
||||
methods that skipped authentication, which gave unauthenticated root on every
|
||||
minion. (Salt advisory, April 2020.)
|
||||
- Lesson: grant typed functions with argument grammar, not a shell; ids belong
|
||||
to the authority; and a root agent's intake is its attack surface, so keep it
|
||||
local and small.
|
||||
|
||||
### Ansible and AWX (Tower)
|
||||
|
||||
- Modules (`ansible.builtin.apt`, `ansible.builtin.systemd_service`) take typed
|
||||
parameters and report changed, ok or failed; `become` is per task.
|
||||
- AWX job templates with RBAC let a user launch only pre-approved templates,
|
||||
with survey fields as typed, validated parameters; the activity stream and
|
||||
job output are the audit. (AWX docs, "Job Templates", "Surveys", "Activity
|
||||
Stream".)
|
||||
- Lesson: "a named operation with validated parameters, launched by a principal
|
||||
who may launch only that" is the mature shape of a typed order.
|
||||
|
||||
### NixOS deploy tools (deploy-rs, colmena, nixos-rebuild)
|
||||
|
||||
- Activation switches a whole system closure; deploy-rs "magic rollback" rolls
|
||||
the activation back unless the deployer confirms it within a timeout over a
|
||||
fresh connection. (deploy-rs README, "Magic Rollback".)
|
||||
- Lesson: a change that can cut off its own operator wants a confirm-or-revert
|
||||
window. For Idunn this already exists for releases (continuity, fencing); it
|
||||
matters for any later host-level order (reboot, network) and for break-glass.
|
||||
|
||||
### polkit and sudoers allowlists
|
||||
|
||||
- polkit rules can grant a user `org.freedesktop.systemd1.manage-units` for
|
||||
named units and verbs only (rules see `action.lookup("unit")` and `"verb"`).
|
||||
(polkit(8), systemd's polkit actions.) The mind units already use a polkit
|
||||
start grant.
|
||||
- sudoers `Cmnd_Alias` allowlists and `log_output` I/O logs are what the interim
|
||||
root (`gamecult-ops deploy/eureka-root`) uses today.
|
||||
- Lesson: a unit allowlist is ordinary practice. polkit alone would give
|
||||
restarts without a single order record, brake gate or #operator post, so it
|
||||
is the smaller tool but not the ruled one.
|
||||
|
||||
## 2. Break-glass access
|
||||
|
||||
- The common pattern (healthcare "break the glass", cloud emergency accounts,
|
||||
Teleport access requests, AWS's guidance on emergency access): the actor
|
||||
states a justification; use raises a loud alert at once; access is
|
||||
time-boxed; the session is recorded; every use is reviewed afterwards.
|
||||
(Teleport docs, "Access Requests" and "Session Recording"; AWS Well-Architected
|
||||
security pillar, emergency access.)
|
||||
- What these systems assume and Yggdrasil lacks: a human on call who sees the
|
||||
alert in minutes. With the operator away, the review is done by Minds and
|
||||
members in #operator, and the alert reaches them only if chat is up.
|
||||
- Lesson: break-glass is defended by visibility and review, not by its
|
||||
intake. It must announce before it runs and keep a full record of what ran.
|
||||
|
||||
## 3. Two-person rule and veto windows
|
||||
|
||||
- Two-person integrity (military nuclear surety; banking dual control): no
|
||||
single person can complete a critical action; a second must positively
|
||||
approve. Software forms: required reviewers on protected branches; Google's
|
||||
multi-party authorization for production changes; Teleport requests needing
|
||||
N approvers.
|
||||
- A veto window is weaker and different: lazy consensus (Apache "lazy
|
||||
consensus": silence means assent after a stated period). It protects only if
|
||||
someone is watching during the window, and an attacker who controls the
|
||||
timing picks the quiet hour.
|
||||
- The ruling in force (`brake-anyone-pulls-motion-releases`) is a veto shape:
|
||||
anyone pulls at once, only a motion releases. Positive approval would need a
|
||||
second principal who is awake; with the operator gone that is another Mind,
|
||||
and Minds read the same chat an injection arrives through.
|
||||
- Lesson: for typed orders the type is the defence (closed operations,
|
||||
validated arguments, an allowlist); for break-glass the window plus the
|
||||
record is the defence, and its strength is the attention of whoever reads
|
||||
#operator. Say so where the window is configured.
|
||||
|
||||
## 4. What this gives the first cut
|
||||
|
||||
- Authenticate by kernel peer credentials on a root-owned local socket; derive
|
||||
the principal and the issuing unit, never accept a declared requester.
|
||||
- Idunn assigns the order id and keeps the only record in its own store;
|
||||
the caller's request is not the record.
|
||||
- Orders are a closed set of typed operations with argument grammar and an
|
||||
allowlist in root-owned configuration.
|
||||
- Every order and its result are posted; the store is the record and the post
|
||||
is its projection.
|
||||
- Break-glass, when it lands, waits on an announcement and a window, and is
|
||||
recorded in full.
|
||||
Loading…
Reference in a new issue