Skip to content

fix(drift): pin the Ollama artifact the drift job unpacks as root - #360

Merged
jpr5 merged 1 commit into
mainfrom
drift/pin-ollama-test-drift
Aug 6, 2026
Merged

fix(drift): pin the Ollama artifact the drift job unpacks as root#360
jpr5 merged 1 commit into
mainfrom
drift/pin-ollama-test-drift

Conversation

@jpr5

@jpr5 jpr5 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What this closes

test-drift.yml's Ollama provisioning step fetched https://ollama.com/install.sh
and ran it with no digest check of any kind — not even the weaker script-only
pin fix-drift.yml carries today.

The step holds no provider key of its own, and that protects nothing. It runs
before Run drift tests, which is handed OPENAI_API_KEY,
ANTHROPIC_API_KEY, GOOGLE_API_KEY, OPENROUTER_API_KEY, FAL_KEY,
COHERE_API_KEY and ELEVENLABS_API_KEY. A payload that cannot read those keys
can still plant a node/npx/git earlier on PATH, and the later key-holding
step executes it.

(The workflow's other 15 secrets. references live in the notify and
drift-live-pr jobs — separate runners, not reachable from this step. Saying so
rather than quoting "22 secrets".)

Watched red-green-rebreak

RED, the committed step's own run: body executed verbatim with curl
serving substituted bytes:

STEP_EXIT=0
SH_RAN argv=…/ollama-install.sh
what sh was handed: ATTACKER-CONTROLLED PAYLOAD

Arbitrary third-party code executed and the step reported success.

GREEN, same harness after the fix:

STEP_EXIT=1
::error::the Ollama v0.32.6 tarball does not match its pinned sha256 —
REFUSING to unpack it as root.

No SH_RAN, no TAR_RAN. The new guard asserts the absence of a payload at an
executor
, not an exit code — and its positive control asserts tar was handed
exactly the verified bytes, so "always refuse" cannot satisfy it.

RE-BREAK, three mutations, each restored (workflow md5 identical before and
after all three): neutering the digest comparison, pointing the fetch back at
install.sh, and emptying the pin each red exactly their intended guard.

The remedy

install.sh is not used. Pinning it would not have been sufficient — it streams
an unversioned, undigested ollama-linux-<arch>.tar.zst into sudo tar -x and
cannot be fixed in place because it never holds the file. So the release artifact
is fetched from an immutable release tag and sha256-verified before anything
unpacks it. Same shape as #359 does for fix-drift.yml; that file is untouched
here.

Digest dec2fa50…aadcfc (v0.32.6, 1,420,686,963 bytes) agreed by three
independent sources verified in this PR
: the release's own sha256sum.txt, the
GitHub release API's asset digest field, and sha256 of the downloaded bytes.
Archive layout confirmed by listing it — 54 entries, bin/ollama + lib/ollama/*.

This is NOT the last unpinned executable in the repo

Swept all 15 workflows. Still unpinned, not fixed here, ranked by blast radius:

  1. publish-release.yml:189pip install hatch, unpinned PyPI package, in the
    job with environment: pypi + id-token: write that publishes aimock-pytest
    to PyPI via OIDC.
  2. fix-drift.yml:90 — the same Ollama defect in its weaker form; fix(drift): the rejection lookup no longer saturates, and the Ollama artifact is pinned #359's.
  3. publish-commit.yml:20npx pkg-pr-new publish; pkg-pr-new is in neither
    package.json nor pnpm-lock.yaml, so npx fetches latest and runs it. No
    repo secrets in that job.
  4. test-pytest.yml:48pip install ./packages/aimock-pytest[test] resolves
    unpinned transitive deps. No secrets in that job.
  5. Toolchain: actions/setup-node's Node download and pnpm/action-setup's pnpm
    (packageManager: pnpm@10.28.2 — a version, no integrity hash). Applies to
    every job including this one.

Not a finding: the git clone of ag-ui is read by static regex parsing, never
executed. Every npx tsx/npx vitest resolves from the lockfile-installed tree.
Every uses: is SHA-pinned.

Gates

pnpm build 0 · pnpm test:drift 0 · tsc --noEmit 0 · pnpm lint 0 ·
pnpm test:exports 0 · prettier clean · zizmor (medium) 0 findings ·
bash -n on 9 run: bodies, 0 failures · commitlint 0.

pnpm test: 5061 passed / 1 failed — ws-framing, a known pre-existing flake;
passes in isolation (24/24, exit 0). Suite 5057 → 5062.

actionlint exits 1 on one pre-existing SC2086 info in the notify job,
identical on origin/main (base L261 = head L329, exactly this diff's offset).

test-drift.yml's provisioning step fetched https://ollama.com/install.sh and ran
it with no digest check of any kind. Executing that step's own run: body verbatim
with curl serving substituted content, `sh` was handed
"ATTACKER-CONTROLLED PAYLOAD" and the step exited 0.

The step holds no provider key itself, and that protects nothing. It runs before
`Run drift tests`, which is handed OPENAI_API_KEY, ANTHROPIC_API_KEY,
GOOGLE_API_KEY, OPENROUTER_API_KEY, FAL_KEY, COHERE_API_KEY and
ELEVENLABS_API_KEY. A payload that cannot read those keys can still plant a
node/npx/git earlier on PATH, and the later key-holding steps execute it.

Pinning install.sh would not have been enough — proven in fix-drift.yml's own
writeup: the script streams an unversioned, undigested ollama-linux-<arch>.tar.zst
through zstd -d into sudo tar -x, and it cannot be fixed in place because it never
holds the file. So install.sh is not used. The release artifact is fetched from an
immutable release tag and its sha256 checked before anything unpacks it, mirroring
the shape fix-drift.yml is getting in #359.

Digest dec2fa50…aadcfc for ollama-linux-amd64.tar.zst v0.32.6 (1420686963 bytes),
agreed by three independent sources verified here: the release's own
sha256sum.txt, the GitHub release API's asset digest field, and sha256 of the
downloaded bytes. Archive layout confirmed by listing it — 54 entries, bin/ollama
plus lib/ollama/*, so -C /usr/local puts the binary on the default PATH.

This is NOT the last unpinned executable in the repo, and the new guard does not
claim otherwise. Still unpinned and not fixed here: `npx pkg-pr-new publish`
(publish-commit.yml) fetches an unlockfiled npm package and runs it; `pip install
hatch` (publish-release.yml) runs an unpinned PyPI package in the job that holds
PyPI OIDC publish rights; `pip install ./packages/aimock-pytest[test]`
(test-pytest.yml) resolves unpinned transitive deps; and in this job the
setup-node and pnpm/action-setup toolchain downloads carry no committed digest.
fix-drift.yml:90 has the same Ollama defect in its weaker form and is #359's.

New guard executes the step rather than reading it: tampered bytes must not reach
`sh` or `tar`, and a positive control asserts tar was handed exactly the verified
bytes. Three mutations confirmed red — neutering the digest comparison, pointing
the fetch back at install.sh, and emptying the pin.
@pkg-pr-new

pkg-pr-new Bot commented Aug 6, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@copilotkit/aimock@360

commit: a272d75

@jpr5
jpr5 marked this pull request as ready for review August 6, 2026 03:22
@jpr5
jpr5 merged commit 9694acb into main Aug 6, 2026
30 checks passed
@jpr5
jpr5 deleted the drift/pin-ollama-test-drift branch August 6, 2026 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant