Files
dejima-ci-hardener/docs/README.md
T
Brad Anderson f6156c2888 Name the tiers after what a job gets, and put the reader first
The README grew alongside the tool and ended up in the order the work
happened rather than the order a reader needs. Three things were wrong with
it. The two-tier split was implicit, so a reader had to sort out which
paragraphs applied to the host they were building. The opening defined the
whole tool as "no Docker socket in job containers, and deny-by-default
egress", which describes one tier only - someone building the other was told
it does things it deliberately will not do. And long-form justification sat
between the reader and the steps.

So the README is now tier-first: pick a tier from a comparison table, then
follow only that tier's half. Everything that is background rather than
instruction moved to docs/reference.md, with docs/README.md indexing it and
the Proxmox runbook. The runbook stays in proxmox/ beside the firewall
template it explains.

The tier names changed with it. `ci` and `runtime` were dejima's words for
these hosts: `ci` distinguishes nothing on a tool whose whole subject is CI,
and `runtime` only means something if you already know dejima's runtime tests
are the workload that forced the tier to exist. They are `confined` and
`privileged` now, after what a job on each is granted. The distinction that
generalises is where the security boundary sits - inside the host for one,
on the hypervisor for the other - and the table leads with it.

`unprivileged`/`privileged` would have been the more standard pairing and was
rejected: two characters apart on a flag where a misread silently produces a
host that looks hardened and is not.

The old --role values still work and say what they are now called rather than
translating silently. examples/ is renamed to match on both sides, so no
file's tier is implied by the absence of a suffix, and the config mounts in
the compose files follow.

Written down explicitly for the first time: the privileged tier has no egress
allowlist by design. Its jobs hold the socket and run in the host's network
namespace, so any filter installed there is one they can flush. Installing it
anyway would leave a host that looks like it has an allowlist, which is worse
than one that plainly does not.

Also adds GPL-3.0-or-later to match dejima: LICENSE plus SPDX headers on the
scripts.

bats test/ passes, 21/21. All four --role values and an invalid one behave as
intended; the compose and act_runner examples still parse.
2026-08-06 19:31:55 -07:00

1.2 KiB

Documentation

The README is the whole of the setup. Everything here is background, deeper explanation, or the reasoning behind a decision that looks arbitrary from outside.

reference.md The two settings named docker.sock, CONFIG_FILE and why an edit can appear to do nothing, the /data volume, compose networks against job networks, whether several runners should share a job network, why the privileged runner is separate, why public egress is not restricted on the node, why the resolver is set per-runner, the cache server
../proxmox/README.md Building the sacrificial VM: node firewall rules and the order they go in, bootstrap, snapshotting clean, and the scheduled rollback
../proxmox/firewall.fw.template The same node firewall as one annotated file, easier to review in one piece than as a table. Reference, not something to install

One document lives outside this repository: dejima's docs/ci.md, which covers why a CI run needs any of this over a sandbox, and why no approval gate is offered. You do not need it to follow the README.