SUPPLY CHAIN: pin CI actions and release OS inputs for repeatable builds #813

Open
opened 2026-10-02 13:14:21 +00:00 by kayg · 5 comments
Owner

Context

Supply-chain audit under #663, origin/dev c4a61e8cf0. Duplicate searches for reproducibility, supply chain and checksum found no issue for this build-input gap.

Evidence and impact

  • .forgejo/workflows/ci.yml:16,18,23 resolves actions/checkout@v4, dtolnay/rust-toolchain@stable and oven-sh/setup-bun@v2. These are mutable action references even though the requested Rust and Bun versions are fixed. The weekly workflow repeats them.
  • Containerfile:1,13,24 uses Bun, Rust and Debian image tags without digests. Its apt-get inputs at lines 16 and 25 resolve current repository versions.
  • deploy/Containerfile.runtime:3 pins the Debian digest and lines 31-80 verify codec tarball SHA-256 values, but apt-get at lines 4 and 125 still reads moving repositories. A digest-pinned base does not freeze newly installed Debian packages.
  • Rust release builds use --locked and Bun uses --frozen-lockfile. Root Cargo registry entries have checksums; the 743 npm release records have integrity values that match registry metadata. These controls do not pin actions, OS packages or base image tags.

The same source revision can therefore execute changed action code or link/install a different native dependency set. This obstructs incident review and reproducible artifact verification. No compromised upstream input or differing binary was demonstrated; this is not a proved supply-chain attack.

Concrete fix

Pin reviewed action commits and image index digests. Use a dated Debian snapshot or a checked package inventory with versions for builder and runtime dependencies. Record these inputs with the release revision; update them through explicit reviewed security-refresh commits. Retain codec tarball hash checks. Do not freeze security updates indefinitely.

Validation

Add a static check for action SHA and base-image digest pins. Build twice from clean caches with one input inventory and compare resolved action/image/package identities. Compare normalized artifact bytes where supported, and report remaining timestamp/build-ID variation rather than claiming bit-identical builds from a lockfile alone. No perf VM or product API probe is needed for this finding.

Non-blocking under CLAUDE.md: no current product security hole was proved.

## Context Supply-chain audit under #663, origin/dev c4a61e8cf090170f35b1bed3350d9de20c83ecd5. Duplicate searches for reproducibility, supply chain and checksum found no issue for this build-input gap. ## Evidence and impact - `.forgejo/workflows/ci.yml:16,18,23` resolves actions/checkout@v4, dtolnay/rust-toolchain@stable and oven-sh/setup-bun@v2. These are mutable action references even though the requested Rust and Bun versions are fixed. The weekly workflow repeats them. - `Containerfile:1,13,24` uses Bun, Rust and Debian image tags without digests. Its apt-get inputs at lines 16 and 25 resolve current repository versions. - `deploy/Containerfile.runtime:3` pins the Debian digest and lines 31-80 verify codec tarball SHA-256 values, but apt-get at lines 4 and 125 still reads moving repositories. A digest-pinned base does not freeze newly installed Debian packages. - Rust release builds use --locked and Bun uses --frozen-lockfile. Root Cargo registry entries have checksums; the 743 npm release records have integrity values that match registry metadata. These controls do not pin actions, OS packages or base image tags. The same source revision can therefore execute changed action code or link/install a different native dependency set. This obstructs incident review and reproducible artifact verification. No compromised upstream input or differing binary was demonstrated; this is not a proved supply-chain attack. ## Concrete fix Pin reviewed action commits and image index digests. Use a dated Debian snapshot or a checked package inventory with versions for builder and runtime dependencies. Record these inputs with the release revision; update them through explicit reviewed security-refresh commits. Retain codec tarball hash checks. Do not freeze security updates indefinitely. ## Validation Add a static check for action SHA and base-image digest pins. Build twice from clean caches with one input inventory and compare resolved action/image/package identities. Compare normalized artifact bytes where supported, and report remaining timestamp/build-ID variation rather than claiming bit-identical builds from a lockfile alone. No perf VM or product API probe is needed for this finding. Non-blocking under CLAUDE.md: no current product security hole was proved.
Author
Owner

Starting #813 on branch job/deps, based at 2f4482ded066d9c5d9c59130377907f7fd2916c9 (job/merge-round-7a). I read the issue, audit evidence, CLAUDE.md, CONTEXT.md and relevant DESIGN sections. I will pin CI and image inputs and add a static regression check for mutable references.

Starting #813 on branch `job/deps`, based at `2f4482ded066d9c5d9c59130377907f7fd2916c9` (`job/merge-round-7a`). I read the issue, audit evidence, CLAUDE.md, CONTEXT.md and relevant DESIGN sections. I will pin CI and image inputs and add a static regression check for mutable references.
Author
Owner

Implemented in b80c2385c: CI and weekly workflows now pin checkout v4.2.2 (11bd719…), rust-toolchain (7e38f4b…, with the exact 1.98.1 input) and setup-bun v2.2.0 (0c5077e…) to full commit SHAs. The root and runtime Containerfiles pin the verified OCI image-index digests. Debian builder/runtime apt installs now use the same signed 2026-10-02 snapshots for Debian and Debian Security, with only Check-Valid-Until disabled for dated metadata. I included the production nested-Podman Containerfile in the apt pin as well.

The #813 regression fixture rejects tag-only actions, tag-only image bases, missing security snapshots and moving apt repositories. The repository check passed. Snapshot InRelease probes returned HTTP 200 for Bookworm and Trixie plus both security suites. A clean double container build has not been run yet; the runtime image compiles codec libraries and is large, so I am recording that as a remaining verification gap rather than claiming byte reproducibility.

Implemented in `b80c2385c`: CI and weekly workflows now pin checkout v4.2.2 (`11bd719…`), rust-toolchain (`7e38f4b…`, with the exact 1.98.1 input) and setup-bun v2.2.0 (`0c5077e…`) to full commit SHAs. The root and runtime Containerfiles pin the verified OCI image-index digests. Debian builder/runtime apt installs now use the same signed 2026-10-02 snapshots for Debian and Debian Security, with only `Check-Valid-Until` disabled for dated metadata. I included the production nested-Podman Containerfile in the apt pin as well. The #813 regression fixture rejects tag-only actions, tag-only image bases, missing security snapshots and moving apt repositories. The repository check passed. Snapshot `InRelease` probes returned HTTP 200 for Bookworm and Trixie plus both security suites. A clean double container build has not been run yet; the runtime image compiles codec libraries and is large, so I am recording that as a remaining verification gap rather than claiming byte reproducibility.
Author
Owner

Completed on branch job/deps. Final head: 306fd0a953.

Pinned workflow actions to full commit SHAs, OCI base/runtime images to index digests, and Debian Bookworm/Trixie apt sources to dated snapshots while retaining signature checks. Added a static policy regression for tag-only actions, moving image tags, and non-snapshot apt sources.

Gate output:

.....
Ran 5 tests in 0.018s

OK
PASS workflow action SHAs, container image digests and dated Debian snapshots

Known gap: the clean container double-build was not run.

Completed on branch job/deps. Final head: 306fd0a953f342395af64cc62f0b18f3416ea95a. Pinned workflow actions to full commit SHAs, OCI base/runtime images to index digests, and Debian Bookworm/Trixie apt sources to dated snapshots while retaining signature checks. Added a static policy regression for tag-only actions, moving image tags, and non-snapshot apt sources. Gate output: ``` ..... Ran 5 tests in 0.018s OK PASS workflow action SHAs, container image digests and dated Debian snapshots ``` Known gap: the clean container double-build was not run.
Author
Owner

P1: Install trusted CA certificates before HTTPS APT access

Evidence: deploy/Containerfile.runtime:8 and :10 select HTTPS snapshot
sources. Line 12 runs apt-get update. Line 15 installs ca-certificates
only after that update. The same order occurs in the second runtime stage
at lines 129–136, Containerfile:38–:43, and
deploy/nested-podman/Containerfile:13–:20.

The Debian slim base has no ca-certificates package. APT verifies HTTPS
with the system CA certificates. Thus a clean stage cannot get the package
index through its new HTTPS sources. This is a static build-failure inference;
this review did not run a container build. The earlier HTTP 200 probes on
the host do not check the slim image's trust store.

Fix: bootstrap CA certificates from the same dated, signature-checked
snapshot over HTTP, then use HTTPS. Alternatively, copy a reviewed CA bundle
into the stage before the first update. Keep APT archive signature checks.
Do not disable TLS verification.

Rule: #813 requires usable, fixed release inputs. Expected result: every
clean Debian stage can fetch its pinned package index and install packages.
Test idea: build the affected stages from empty caches and verify the
resolved package identities. Extend the static fixture to check this order.

Sources:

Tracking: duplicate search for certificate and snapshot found #813 as the
existing owner for this fix. Evidence is assigned to #813.

## P1: Install trusted CA certificates before HTTPS APT access Evidence: `deploy/Containerfile.runtime:8` and `:10` select HTTPS snapshot sources. Line 12 runs `apt-get update`. Line 15 installs `ca-certificates` only after that update. The same order occurs in the second runtime stage at lines 129–136, `Containerfile:38`–`:43`, and `deploy/nested-podman/Containerfile:13`–`:20`. The Debian slim base has no `ca-certificates` package. APT verifies HTTPS with the system CA certificates. Thus a clean stage cannot get the package index through its new HTTPS sources. This is a static build-failure inference; this review did not run a container build. The earlier HTTP 200 probes on the host do not check the slim image's trust store. Fix: bootstrap CA certificates from the same dated, signature-checked snapshot over HTTP, then use HTTPS. Alternatively, copy a reviewed CA bundle into the stage before the first update. Keep APT archive signature checks. Do not disable TLS verification. Rule: #813 requires usable, fixed release inputs. Expected result: every clean Debian stage can fetch its pinned package index and install packages. Test idea: build the affected stages from empty caches and verify the resolved package identities. Extend the static fixture to check this order. Sources: - [Debian slim package list](https://github.com/debuerreotype/docker-debian-artifacts/blob/dist-amd64/trixie/slim/rootfs.manifest) - [APT HTTPS documentation](https://manpages.debian.org/trixie/apt/apt-transport-https.1.en.html) Tracking: duplicate search for certificate and snapshot found #813 as the existing owner for this fix. Evidence is assigned to #813.
Author
Owner

Fixed the P1 in #813 on job/deps at 656aafd6a. Each production APT stage now fetches the dated Debian and security snapshots over HTTP, installs ca-certificates while APT still verifies signed Release metadata, then switches to the same snapshot over HTTPS. This covers the root builder and runtime, codec builder and nested runtime in Containerfile and deploy/Containerfile.runtime, plus deploy/nested-podman/Containerfile.

The static regression rejects missing CA bootstrap and HTTPS-first ordering. Focused output:

.......
----------------------------------------------------------------------
Ran 7 tests in 0.002s

OK
PASS workflow action SHAs, container image digests and dated Debian snapshots

A clean container build remains for the merge round, as required by the verification policy.

Fixed the P1 in #813 on `job/deps` at `656aafd6a`. Each production APT stage now fetches the dated Debian and security snapshots over HTTP, installs `ca-certificates` while APT still verifies signed Release metadata, then switches to the same snapshot over HTTPS. This covers the root builder and runtime, codec builder and nested runtime in `Containerfile` and `deploy/Containerfile.runtime`, plus `deploy/nested-podman/Containerfile`. The static regression rejects missing CA bootstrap and HTTPS-first ordering. Focused output: ``` ....... ---------------------------------------------------------------------- Ran 7 tests in 0.002s OK PASS workflow action SHAs, container image digests and dated Debian snapshots ``` A clean container build remains for the merge round, as required by the verification policy.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#813
No description provided.