Files
Brad Anderson 6e94695aa6
tests / tests (pull_request) Failing after 1m50s
tests / compose-schema (pull_request) Successful in 1m38s
tests / runner-env (privileged) (pull_request) Successful in 1m23s
tests / runner-env (confined) (pull_request) Failing after 3m9s
Assert on the runners, from inside a job on each
The README pointed at dejima's test/ci-runner.bats to verify runners this
repository builds. That is backwards twice over: it makes the tool's own
correctness depend on a suite in another repository, and it means this
repository ships the hardening with no check that the hardening took.

It is also the only check that can be made. install.sh reports what it wrote.
dejima-ci-runners reports that a runner registered and is reading the config it
generated. A runner can do both of those while handing every job the Docker
socket and unrestricted egress, because neither failure is visible from the
host or from the forge - they are visible from inside a job and nowhere else.

So test/ci-runner.bats lands here, in this repository's vocabulary rather than
dejima's: DEJIMA_CI_TIER is confined or privileged, matching the tier names
everywhere else and the names of the jobs that set it. The old spellings, and
dejima's sandbox/host-docker, are rejected by name rather than falling through
to "unknown" - a workflow that has not caught up should say so.

Nine assertions. Both tiers check the grant that decides everything, in both
directions: the confined tier must not have the socket, the privileged tier
must, and one test fails if both report the same answer, since that means the
labels are not routing to two different runners and the tiering exists only on
paper. The privileged tier also asserts the host network namespace, its second
grant and the reason its jobs have no allowlist in front of them.

The egress half is scoped to the confined tier deliberately. The privileged
tier's jobs are in the host netns, so the bridge rules are not in front of them
and asserting an allowlist there would test nothing and pass anyway - which is
exactly the failure mode this file exists to catch.

Two workflow jobs run it, one per tier, so a broken runner produces one red
check that says which. They name the head for now and become bare checkouts in
the same follow-up that drops the pull_request trigger: the assertions should
come from the base branch so a branch can neither weaken nor delete them, but
this file does not exist on main until this merges, so a bare checkout today
would fail on a missing file rather than on anything about the runner. The
header says both changes.

.dejima/allowed-domains declares deb.debian.org, which the confined job installs
bats from and then asserts an off-list name does not resolve - this file is what
separates those two outcomes. It is also in install.sh's suggested base-domains,
so on most hosts it restates rather than widens; stated anyway, because a job
depending on the operator having accepted a suggestion breaks on a host set up
slightly differently, and declaring what you need is the point of the format.

Tested: bats test/ is 56 ok, 10 skipped, 0 failed. Every DEJIMA_CI_TIER value
exercised - confined and privileged select disjoint assertions, old and unknown
spellings are refused. In this sandbox the confined socket checks pass and the
positive control for egress fails, which is correct: it is not a CI runner, and
a control that passed here would be the bug.
2026-08-06 23:13:34 -07:00
..