Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions docs/design/dann-deployment-threat-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ operator-managed end to end:
- The audit ledger is service-owned, and root can re-chain it from genesis (the
chain has no external anchor), so **audit is not tamper-evident against the
operator.**
- sudoers applies tags last-match-wins, so the `SETENV` tag on the wheel rule
(`%wheel ALL=(ALL:ALL) NOPASSWD:SETENV: ALL`) wins for the operator regardless
of the module's own NOPASSWD grant lines (which carry no `SETENV` tag). The
real route is `sudo -u <svc> env VAR=… $BROKER …`, which reaches the broker
with caller-chosen variables that `purge_ambient_env` does not cover. This is
moot while the operator is root — which is the point — and it is a reason
never to deploy this pattern on a host where the operator is *not* already
- sudoers applies tags last-match-wins. For the broker command itself the
module's line matches last and carries no `SETENV`, so a `sudo VAR=… -u <svc>
$BROKER …` is refused; the wheel rule's `SETENV`
(`%wheel ALL=(ALL:ALL) NOPASSWD:SETENV: ALL`) still covers the `env` form,
`sudo -u <svc> env VAR=… $BROKER …`, which reaches the broker with
caller-chosen variables that `purge_ambient_env` does not cover. This is moot
while the operator is root — which is the point — and it is a reason never to
deploy this pattern on a host where the operator is *not* already
root-equivalent.

So on dann, sudo-secretspec provides exactly two things, and it is worth naming
Expand Down
28 changes: 14 additions & 14 deletions nix/module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -229,19 +229,19 @@ in
# The whole policy — the `Defaults!` line *and* the operator's NOPASSWD
# grant lines — comes from `sudoersText`, the IFD derivation that runs the
# binary's own `print-sudoers`. `security.sudo.extraConfig` is
# `types.lines`, merged by plain `concatStringsSep "\n"` with no
# `sortProperties` pass, so `mkOrder`/`mkAfter` carry no weight here; what
# actually orders it is nixpkgs' `sudo.nix`, which appends `extraConfig`
# LAST — after the stock `%wheel` `extraRules` block. sudoers is
# last-match-wins, so these grants are the final lines and take effect over
# `%wheel`'s password prompt. The only residual is ordering against a
# *second* module that also sets `extraConfig`: nixpkgs emits both in the
# order its `concatStringsSep` sees them, and whichever lands later wins.
# That is an availability-only risk (a later rule could re-prompt for a
# verb), never an escalation — it cannot add a grant this module did not
# already emit. There is no `timestamp_timeout=0` line and no `doctor` grant
# on Linux: the former has no client path to attach to, the latter refuses
# on Linux.
security.sudo.extraConfig = builtins.readFile sudoersText;
# `types.lines`; `lib.mkAfter` sorts this definition after other modules'
# `extraConfig` lines (nixpkgs runs `sortProperties` whenever any
# definition carries `_type == "order"`, before the type's merge), and
# nixpkgs' `sudo.nix` appends `extraConfig` LAST — after the stock `%wheel`
# `extraRules` block. sudoers is last-match-wins, so these grants are the
# final lines and take effect over `%wheel`'s password prompt. The only
# residual is ordering against a *second* module that also sets
# `extraConfig` with `mkAfter` (or a later `mkOrder`): whichever sorts
# later wins. That is an availability-only risk (a later rule could
# re-prompt for a verb), never an escalation — it cannot add a grant this
# module did not already emit. There is no `timestamp_timeout=0` line and
# no `doctor` grant on Linux: the former has no client path to attach to,
# the latter refuses on Linux.
security.sudo.extraConfig = lib.mkAfter (builtins.readFile sudoersText);
};
}
Loading