feat(images): build on rootless BuildKit over mTLS; verification moves into Containerfile verify stages
Operator decision on PR #81: no CI job may reach a privileged daemon. The act runner is untouched. - platform/buildkit (+ clusters/base/buildkit.yaml): moby/buildkit v0.34.1-rootless pinned by digest, uid 1000, not privileged; caps drop ALL + SETUID/SETGID, seccomp/AppArmor Unconfined, read-only rootfs (each measured under podman). cert-manager CA + server/client certs, ClusterIP :1234, default-deny with ingress only from the act-runner pod (DinD masquerades jobs to it). No Kyverno exception: every applied policy matches app-namespace=true only. - Each Containerfile names its shipped stage and ends in a `verify` stage holding every former `docker run` assertion (uid 65532, RUN --network=none, writable-path inventory standing in for the read-only rootfs). The old `&& echo` checks that could never fail are real assertions now. - images.sh drives buildkitd with a pinned buildx (sha256-checked) via bake; PRs build verify targets with agent-runner FROM the in-run toolbox (target: context); main verifies, then pushes. Fails loudly when the builder secrets are absent or buildkitd is unreachable. - infra/gitea/buildkit-client-secret.sh copies the client cert into Actions secrets. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
65a7769f55
commit
310deb0f7d
28 files changed
+1490
-608
No files matched your search
@@ -120,10 +120,20 @@ CI. That is a real coverage gap, not a phase.
|
||||
This repo's three images — `toolbox` (`infra/devcontainer/`), `agent-runner` (`infra/agent/`,
|
||||
built `FROM` the toolbox) and `conformance-runner` (`conformance/incluster/`) — are built,
|
||||
verified and published by [`images.yaml`](images.yaml), never from a workstation
|
||||
(operator rule, 2026-10-29). The logic is in [`scripts/images.sh`](scripts/images.sh); each
|
||||
image is built by **its own** `build-image.sh`, the same script a developer runs locally, so the
|
||||
in-image verification (non-root uid, read-only rootfs, tool presence, `PM_SELFTEST=1
|
||||
pm-dispatch`, the `conformance-clone` refusals) exists once.
|
||||
(operator rule, 2026-10-29). The logic is in [`scripts/images.sh`](scripts/images.sh).
|
||||
|
||||
**The builder is rootless BuildKit** ([`platform/buildkit/`](../../platform/buildkit/README.md)),
|
||||
reached over mTLS with a pinned `buildx` — no job here touches a Docker daemon, privileged or
|
||||
otherwise (operator decision on PR #81). The client certificate reaches jobs as the Actions
|
||||
secrets `BUILDKIT_CA`, `BUILDKIT_CLIENT_CERT`, `BUILDKIT_CLIENT_KEY`.
|
||||
|
||||
**Verification is a build target.** Each Containerfile ends in a `verify` stage that runs every
|
||||
in-image assertion at build time as the non-root uid with `RUN --network=none` (tool presence and
|
||||
pinned versions, `PM_SELFTEST=1 pm-dispatch`, the pm-worker probe, the `conformance-clone`
|
||||
refusals, no writable path outside the workspace). The pipeline builds `<image>-verify` before it
|
||||
builds, let alone pushes, the image. Build args come from each image's own
|
||||
`build-image.sh --print-build-args`, which is also the local podman path — so the recipe and the
|
||||
proof exist once.
|
||||
|
||||
| Trigger | What happens |
|
||||
|---|---|
|
||||
@@ -143,8 +153,10 @@ account with package write on the org). The automatic Actions token cannot push
|
||||
[`infra/gitea/registry-retention.sh`](../../infra/gitea/registry-retention.sh), an operator
|
||||
action, keeps every digest git pins plus the newest tags.
|
||||
|
||||
Cost on this runner: the job shares the single act_runner slot with the gate, and the DinD store
|
||||
is a node `emptyDir`; the job prunes it on exit.
|
||||
Cost: the job shares the single act_runner slot with the gate, but the build itself runs in the
|
||||
`buildkitd` pod, not in DinD, so the runner's disk and memory are untouched. Until
|
||||
`platform/buildkit` is deployed and its client certificate copied
|
||||
(`infra/gitea/buildkit-client-secret.sh`), the job fails loudly at its builder preflight.
|
||||
|
||||
## Files
|
||||
|
||||
|
||||
Reference in new issue
Block a user