Repository navigation
Conversation
LLVM archives were downloaded without a checksum in CI, in the release jobs and in the LLVM distribution workflow; Node and Zig for the Sandbox image were checked against a checksum list fetched from the same origin as the archive. - scripts/toolchain.sha256 holds the SHA-256 of every toolchain archive that CI, the release jobs and the Sandbox image download (LLVM for Linux x64 and arm64 and for Windows, the LLVM sources, Node, Zig, the LLVM apt key), and scripts/verify-toolchain.sh checks a file against it. Every download runs the check before the file is unpacked; a different digest or a file with no pin fails. - The Linux LLVM cache key is the hash of the pin file, so a cache never outlives the digest its archive was checked against. - Every action is referenced by commit with its version in a comment, and Dependabot proposes the updates once a month. - ci.yml and release.yml get top-level permissions (contents: read); the jobs that publish, read other runs' artifacts or write the GitHub release already declare what they need. - tests/harness/ci-supply-chain.test.ts enforces the three rules. - .dockerignore lets the Sandbox image build see the three scripts its Dockerfile copies. Co-Authored-By: Claude Code <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
The seed contract test found the upload and download steps by their tag (actions/upload-artifact@v4). The actions are pinned to commits now, so the lookup returned undefined and the test threw. Select them by name, as the test plan's test already does. Co-Authored-By: Claude Code <noreply@anthropic.com>
|
The four red macOS jobs on bd83d90 fail on two corpus programs that this change does not touch, and both fail the same way without it:
Every other check passed, including the jobs this change affects: the Linux and Windows LLVM downloads with the digest check, every job that uses a pinned action, and the bootstrap seed contract test fixed in bd83d90. The aggregate |
|
Superseded by train security-1, #3430. The train carries this branch at bd83d90, merged with current main: main's retry settings are kept inside this branch's download-then-check steps, and the eleven 🤖 Generated with Claude Code |
Toolchain downloads are checked against pinned SHA-256 digests and actions are referenced by commit (vercel-labs#3185). Conflicts, resolved by reading both sides: - .github/actions/native-packages/action.yml: the helper cache key from the train (with the evaluator's inputs), main's comment, and the branch's commit pin on the cache step below it. - .github/workflows/ci.yml and release.yml, the Windows LLVM steps: the branch's layout stays (one step downloads and checks the archive, the next unpacks it), so main's download line inside the unpack step is gone; the download keeps main's five attempts thirty seconds apart. - .github/workflows/llvm-dist.yml and release.yml, the Linux LLVM steps: the branch's check after each download, with main's retry settings. Main gained eleven `uses:` lines by tag after the branch was cut (the ICU download cache action, two cache steps of the native packages action, the generative workflow, one job of ci.yml and one step of release.yml). They are pinned here to the same commits as the rest; each of the seven pinned actions was checked against GitHub: its version tag names that commit. Co-Authored-By: Claude Code <noreply@anthropic.com>
What changes
LLVM archives were downloaded without a checksum in CI, in the release jobs and in the LLVM distribution workflow. Node and Zig for the Sandbox image were checked against a checksum list fetched from the same origin as the archive. Actions were referenced by tag, and
ci.ymlandrelease.ymlhad no top-levelpermissionswhile the repository's default token can write.scripts/toolchain.sha256holds the SHA-256 of every toolchain archive that CI, the release jobs and the Sandbox image download: LLVM 22.1.8 for Linux x64, Linux arm64 and Windows, the LLVM sources, Node 24.22.1, Zig 0.16.0 for both Linux architectures, and the key that signs the LLVM apt packages.scripts/verify-toolchain.sh <file> [<name>]checks a file against it and fails on another digest or on a file with no pin. It is POSIX sh because the Sandbox image downloads Node before it has Node, and it runs in Git Bash on the Windows runners..github/actions/llvm-linux, the Windows LLVM step ofci.yml, the Linux and Windows LLVM steps ofrelease.yml, both archives inllvm-dist.yml,scripts/sandbox-bootstrap.sh,scripts/install-zig.shandDockerfile.sandbox. A version bump without a new line in the pin file fails withpins no SHA-256 for <file>.uses:lines name a 40-digit commit with the version in a comment (actions/checkout@11d5960… # v4.4.0); each commit is what the tag pointed to today..github/dependabot.ymlproposes updates once a month as one pull request. If you would rather move the pins by hand, drop that file; nothing else depends on it.ci.ymlandrelease.ymlget top-levelpermissions: contents: read.tests/harness/ci-supply-chain.test.tsfails on auses:that is not a commit with a version comment, on a workflow without top-levelpermissions, on a malformed pin file, and on a file that downloads from LLVM's releases, nodejs.org, ziglang.org or the apt key URL without running the verifier..dockerignoreexcludedscripts/install-zig.sh, whichDockerfile.sandboxalready copied; it now lets through the three scripts the image build copies.Where the digests come from
Each was computed from a download in a Sandbox and compared with a second source: GitHub's release-asset digests for the four LLVM files, Node's
SHASUMS256.txt, and Zig's download index. All agree.Permissions: what each job uses
ci.yml: no job writes to the repository, comments, or requests an OIDC token. Checkout needscontents: read; caches and artifacts use the runner's own token.validation_scopeandlanesalready declared theirs.release.yml:check-release,cli-profile,publish(id-token: write,actions: read),npm-availableandgithub-release(contents: write,actions: read) already declare what they use and are unchanged. The two jobs without a block,build-native-packagesandbuild-mobile-runtime-packs, check out, build and upload artifacts, and now getcontents: readinstead of the repository default.permissions.Checked
In a Sandbox (Ubuntu x86-64, 8 vCPU, Xeon 2.90 GHz):
verify-toolchain.shaccepts all eight downloaded files, rejects a wrong file under a pinned name and a file with no pin.scripts/sandbox-bootstrap.shruns to the end with the committed pins; with a wrong digest for the apt key or for Node it stops at that file before using it; with a Node version that has no pin it stops.scripts/install-zig.shinstalls with the committed pin and stops on a wrong one.ci-supply-chain,ci-stack-scope,ci-lanes,sandbox-configandnode-pintests: 89 pass.pnpm lint,pnpm format:check. Every workflow and action parses.Not exercised
release.yml's Linux and Windows LLVM download steps and its new top-levelpermissionsonly run in a release. The Windows steps are the same lines asci.yml's, which this pull request's own run exercises; the Linux arm64 archive's digest was checked against a download but no arm64 job runs here. Nothing else in the release changes.llvm-dist.yml(manual) and thedocker buildofDockerfile.sandbox(no Docker in the Sandboxes).Not pinned by digest
Homebrew's LLVM on the macOS runners; container images referenced by tag (manylinux for the libnode packs,
node:24-bookworm-slim,alpine:3.22,amazonlinux:2023); the Android NDK throughsdkmanager; thetsc-tscheckout used as profile training input; and the profiled LLVM distribution from this repository's own release, which is checked against a.sha256from the same release.One-time cost
The cache keys of the Linux LLVM, the LLVM helpers and the runtime packs include the files this changes, so the first run after it lands downloads LLVM again (now verified) and rebuilds the helper and pack caches once.
🤖 Generated with Claude Code