- Python 92%
- Shell 4.5%
- Dockerfile 3.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .dockerignore | ||
| Dockerfile | ||
| Dockerfile.system-hz-hermetic | ||
| Dockerfile.system-hz-r2-provider | ||
| Dockerfile.system-hz-rust-osv | ||
| Dockerfile.system-hz-rust193 | ||
| Dockerfile.system-hz-rust199 | ||
| LICENSE | ||
| osv-rust-snapshot.json | ||
| README.md | ||
| README.system-hz-rust199.md | ||
| rust193-inputs.json | ||
| rust199-inputs.json | ||
| supplychain-hermetic | ||
| system-hz-rust-select.sh | ||
| test-installed-system-hz-rust193-host.py | ||
| test-installed-system-hz-rust193.py | ||
| test-installed-system-hz-rust199.py | ||
| test-rust-osv-offline.py | ||
| test-system-hz-hermetic.sh | ||
| test-system-hz-r2-provider.sh | ||
| test-system-hz-rust-osv.py | ||
| test-system-hz-rust193.py | ||
| test-system-hz-rust199.py | ||
| verify-installed-system-hz-rust193-host.py | ||
| verify-installed-system-hz-rust193.py | ||
| verify-installed-system-hz-rust199.py | ||
act-node-docker
Forgejo Actions compatible runner image with Node.js, Docker CLI, Kubernetes tools, and infrastructure CLIs for use with Forgejo Actions (act-runner).
The canonical source is https://git.noel.sh/noel/act-node-docker.
Features
- Based on
catthehacker/ubuntu:act-latest(GitHub Actions compatible) - Node.js pre-installed (for GitHub Actions that require it)
- Docker CLI with Buildx and Compose plugins
- Kubernetes tooling with
kubectlandkustomize - Infrastructure tooling with
atmos,tofu,infisical,jq, andripgrep - Hermetic source security tooling with
supplychain, OSV Scanner, Gitleaks, zizmor, and a digest-pinned PyPI vulnerability snapshot - Codewire CI native tooling with Protocol Buffers compiler and well-known
type headers, PostgreSQL client,
pkg-config, GTK 3, WebKitGTK 4.1, and XKB X11 development metadata - A system-cluster hermetic derivative with checksum-pinned Helm and ShellCheck
- Checksum-pinned Kind for disposable exact-image integration gates
- Checksum-pinned sccache for host Rust compilation against disposable local or explicitly configured remote cache backends
- The checksum-pinned Cilium
1.19.5chart for networkless bootstrap rendering - Checksum-pinned PyYAML for offline manifest contract validation
- Checksum-pinned Ubuntu runtime packages required by pinned Chromium browser verification, installed during the networkless build phase
- A sealed-input build contract: an external tokenless fetch phase verifies the exact SHA-256 inputs, then BuildKit mounts them read-only and runs every Dockerfile step with networking disabled
- Compatible with act-runner's Docker-in-Docker setup
Usage
System CI
docker pull nexus-system-hz-eu-1.tail.noel.sh/oci-approved/act-node-docker@sha256:c9f5387dc5b0ec128af3b16002ebd30d1323bc51bc511404c4c8b22a6288952c
The former Docker Hub image is retained only as the immutable bootstrap base
recorded in infrastructure provenance. New system CI artifacts are published
to Nexus and consumed by digest through oci-approved.
Forgejo Runner Configuration
Configure your act-runner labels to use this image:
runner_labels:
- "ubuntu-latest:docker://nexus-system-hz-eu-1.tail.noel.sh/oci-approved/act-node-docker@sha256:c9f5387dc5b0ec128af3b16002ebd30d1323bc51bc511404c4c8b22a6288952c"
- "ubuntu-22.04:docker://nexus-system-hz-eu-1.tail.noel.sh/oci-approved/act-node-docker@sha256:c9f5387dc5b0ec128af3b16002ebd30d1323bc51bc511404c4c8b22a6288952c"
- "ubuntu-24.04:docker://nexus-system-hz-eu-1.tail.noel.sh/oci-approved/act-node-docker@sha256:c9f5387dc5b0ec128af3b16002ebd30d1323bc51bc511404c4c8b22a6288952c"
Docker Socket Access
For jobs that need to build Docker images, mount the Docker socket from the DinD sidecar. In your act-runner Helm values:
container:
options: "-v /var/run/docker.sock:/var/run/docker.sock"
Building Locally
docker build -t act-node-docker:latest .
Offline Cloudflare provider layer
Dockerfile.system-hz-r2-provider adds the Cloudflare 5.24.0 Linux amd64
provider archive to the existing system CI image
sha256:2cbc40c091b1e5e3b48214e208d9fdff30a4f0afda5e661b5c6cde977b7f3bca.
The parent uses the publisher's oci-promoted/act-node-docker reference;
consumers retain their separate oci-approved pull path. The derivative
inherits that image's toolchain and keeps the existing 16-input
Dockerfile.system-hz-hermetic recipe unchanged.
The sealed _build_inputs directory contains this single public input:
| Archive | SHA-256 |
|---|---|
terraform-provider-cloudflare_5.24.0_linux_amd64.zip |
2390fc5df95addfd47d3f638964a1f9f6192a8c84ad3b1eab554ef88e0ac4091 |
The archive comes from the upstream
Cloudflare release.
Its checksum matches the Codewire R2 lifecycle component's lockfile. The
networkless build checks the input and installed bytes, requires a full
lowercase source commit through SOURCE_REVISION, and installs the archive
with root ownership and mode 0444 at:
/opt/infra-artifacts/tofu-providers/registry.opentofu.org/cloudflare/cloudflare/terraform-provider-cloudflare_5.24.0_linux_amd64.zip
The consumer selects this packed filesystem mirror through a private OpenTofu
CLI configuration and uses its readonly dependency lockfile. It does not need
provider credentials for mocked plan tests. A filesystem mirror and
TF_PLUGIN_CACHE_DIR must be separate directories.
Run ./test-system-hz-r2-provider.sh for source-boundary checks and synthetic
installation tests. These do not build an image or execute a provider. The
existing separated prefetch/publisher Flux transaction documented in infra's
docs/runbooks/nexus-oci-bootstrap.md owns publication. It seals the reviewed
source and archive before the credential-bearing networkless build. Published
image acceptance must execute the real offline mocked plans and existing
toolchain checks before infra adopts its digest. The source, revision and
approved parent are recorded in OCI labels.
Offline Rust advisory database layer
Dockerfile.system-hz-rust-osv adds only the crates.io OSV snapshot described in
osv-rust-snapshot.json to the accepted R2-provider image
sha256:36ed662b60eac8f9ee826a88288ec88feb3cd07d4a057352ffcac77a25a38ce0.
The existing binaries, Cloudflare provider and PyPI snapshot are inherited
unchanged. This supplies offline Rust dependency coverage; it is not a scanner-policy
exception or a claim that the inherited PyPI snapshot was refreshed.
Prefetch the generation-bound public URL into _build_inputs under the exact
manifest filename. Verify its committed checksum before sealing and again in
the publisher. The networkless recipe installs root-owned, read-only database
bytes at /opt/supplychain/cache/osv-scanner/crates.io/all.zip. OSV exports are mutable;
the recorded generation, timestamp and digest identify one snapshot, not a
perpetual latest version. An unavailable generation or checksum mismatch must
fail closed and requires a reviewed new pin, never an automatic re-pin.
test-system-hz-rust-osv.py checks the source boundary and exercises installation
with synthetic bytes. test-rust-osv-offline.py ARCHIVE exercises the actual
scanner against the pinned public snapshot using generated vulnerable/fixed
Cargo lockfiles and missing/corrupt database cases; it uses no credentials or
network-capable scan flags. Neither test is proof of a published image.
Publication follows Infra's existing separated prefetch/publisher Flux transaction. Before adopting the new digest, verify its registry manifest and labels through the pull-only identity, then run the real offline scanner and still-consumed supplychain revisions as UID1000 in a deny-all-egress pod with no credential mounts. Preserve package discovery, vulnerability detection and fail-closed missing-data behavior. Then rerun the affected exact-head source approval; finding a genuine dependency advisory must remain a failure.
Sealed Rust 1.93 leaf
Dockerfile.system-hz-rust193 installs the five checksum-pinned Rust 1.93.0
inputs from rust193-inputs.json over its immutable parent. GNU, static musl,
ARM GNU and both Darwin standard libraries share the sealed
/opt/infra-rust/1.93.0 prefix. Its fixed rustup interface reports those
targets and refuses toolchain mutation with exit 64. The inherited provider,
advisory databases and tools remain part of acceptance.
test-system-hz-rust193.py checks the recipe and synthetic installation.
test-installed-system-hz-rust193.py checks concrete refusals, including
changed fixture identities, absent scanner discovery or mock-plan results,
bounded child output and cleanup of a detached child after a deadline.
Neither test qualifies an installed image.
The installed verifier runs inside an isolated Linux amd64 container:
python3 -I -B /verification/verify-installed-system-hz-rust193.py /verification/consumers
Before running it, the host must bind the exact image ID, parent layers and source labels, seal the verifier and its closed public consumer inventory, and inspect the complete container configuration. Run as UID and GID 1000 with a read-only root, no network, no credentials or sockets, and bounded resources and lifetime. The only writable mounts are owned disposable work and temporary directories; kill and reap the owned process family before cleanup. Guest checks supplement this host inspection.
Acceptance executes the retained Codewire runner assertion, genuine GNU and static musl compiler probes, fmt and Clippy, all five installed standard libraries, the fixed toolchain mutation refusal, four offline scanner cases and both retained supplychain revisions. It also executes Infra's exact public R2 lifecycle test entrypoint and requires all 11 real OpenTofu mock plans and their successful summary. The provider and advisory archive hashes are checked before and after the run. This verifier does not replace or relabel an older Kubernetes Job result.
Private registry pull access, publication and infrastructure adoption are separate actions. A passing source test or local image verification does not publish an image or change runner configuration.
What's Included
| Tool | Version | Notes |
|---|---|---|
| Node.js | Latest from base image | For GitHub Actions |
| npm | Latest from base image | Package manager |
| Docker CLI | Latest stable | Client only, connects to external daemon |
| Docker Buildx | Latest stable | Multi-platform builds |
| Docker Compose | Latest stable | v2 plugin |
| kubectl | 1.36.1 | Kubernetes client |
| kustomize | 5.8.1 | Kubernetes manifest customization |
| atmos | noeljackson/atmos d64609ef8 | Stack and workflow orchestration with Hetzner auth support |
| supplychain | noeljackson/supplychain ee0abebcd | Strict source security gate with fail-closed OSV offline mode |
| OSV Scanner | 2.4.0 | Uses the image's digest-pinned PyPI database in hermetic workflows |
| Gitleaks | 8.30.1 | Redacted repository secret scanning |
| zizmor | 1.25.2 | Offline GitHub/Gitea workflow audit |
| OpenTofu | 1.11.6 | Terraform-compatible IaC |
| Infisical CLI | 0.43.58 | Secret injection |
| jq | OS package | JSON processing |
| ripgrep | OS package | Fast repository search |
| protoc and Protobuf headers | OS packages | Rust and Connect contract generation, including well-known types |
| PostgreSQL client | OS package | Database and integration verification |
| GTK/WebKitGTK/XKB development metadata | OS packages | Codewire GPUI/Wry Linux verification |
| Helm | 3.16.4 | Added by Dockerfile.system-hz-hermetic for offline runner validation |
| ShellCheck | 0.11.0 | Added by Dockerfile.system-hz-hermetic for offline shell validation |
| Kind | 0.32.0 | Added by Dockerfile.system-hz-hermetic for offline disposable cluster tests |
| sccache | 0.17.0 | Checksum-pinned static musl binary for host Rust compilation |
| Cilium chart | 1.19.5 | Stored at /opt/infra-artifacts/cilium-1.19.5.tgz for networkless rendering |
| PyYAML | 6.0.2 | Checksum-pinned CPython 3.12 amd64 wheel for manifest contract validation |
| Chromium native runtime | Noble-pinned | ALSA, NSPR, and NSS libraries installed from four checksum-pinned sealed .deb inputs |
License
MIT