Supply-chain security: config and pipeline reading
Crux Read real manifests, lockfiles, a cosign verify, and a CI workflow, predict the supply-chain behaviour, and pick the highest-leverage fix.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at senior altitude — in orbit
◷ 14 min
Supply-chain problems live in manifests, lockfiles, and pipeline YAML — not in your application code. Read each snippet, predict where the install step is exposed, and choose the fix a senior engineer would make first.
Goal
Practise the loop you run in every supply-chain review: read the manifest and pipeline, predict where untrusted bytes or untrusted code can enter, and reach for the highest-leverage control before adding more scanning.
Snippet 1 — the manifest
// package.json — and the CI step that installs it{ "dependencies": { "left-pad": "^1.3.0", "@acme/billing": "^2.0.0" }}// CI: run: npm install
Quiz
Completed
Two things here weaken the install step. Which pair, and what is the single highest-leverage fix?
Heads-up Whether a specific package is fashionable is not the supply-chain defect. The defect is loosened ranges plus a non-enforcing install command that lets new or tampered bytes in.
Heads-up Dependency classification does not change install-step integrity. The exposure is the caret range and `npm install` over `npm ci`, regardless of which section the package sits in.
Heads-up `npm install` will rewrite the lockfile to satisfy a loosened range, so the hash it checks is whatever it just resolved. Only `npm ci` against a committed lockfile enforces the recorded hashes.
Snippet 2 — manifest vs lockfile
# package.json says:"@acme/ui": "^3.1.0"# package-lock.json (committed) pinned:"@acme/ui": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@acme/ui/-/ui-3.1.0.tgz", "integrity": "sha512-Abc123..." }# A new 3.4.0 was published yesterday. CI runs `npm ci`.
Quiz
Completed
With `npm ci` and this committed lockfile, which version installs, and what is the integrity field doing?
Heads-up `npm ci` does not consult the caret range; it installs the lockfile verbatim. The caret only matters when you deliberately run an update that regenerates the lock.
Heads-up The integrity field is enforced: npm hashes the downloaded tarball and compares to the recorded sha512, failing on any mismatch. That is the byte-tamper guarantee.
Heads-up Under `npm ci` the lockfile is authoritative, not advisory: version and integrity hash are both enforced, and a mismatch errors out.
Snippet 3 — verifying provenance
# Release pipeline signs the image; deploy gate verifies before rollout:cosign verify \ --certificate-identity-regexp "https://github.com/acme/.*" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ ghcr.io/acme/api@sha256:9f2b... # pinned by digest, not :latest
Quiz
Completed
What does this cosign verify gate actually guarantee, and why is the @sha256 digest (not :latest) important?
Heads-up cosign verifies signatures and provenance identity, not vulnerabilities. CVE scanning is a separate step against the SBOM; verify answers authenticity, not patch state.
Heads-up A signature proves who built it and that it is untampered since signing — not that the source was benign. A compromised but legitimately-signed build still verifies; signing reduces impostor risk, not insider risk.
Heads-up A tag is mutable: :latest can be repointed to a different image after you verify. Pinning by digest binds the verification to the exact immutable bytes you deploy.
Snippet 4 — the CI workflow
on: pull_request_target: # runs in the BASE repo contextjobs: build: permissions: contents: write packages: write steps: - uses: actions/checkout@v4 with: { ref: ${{ github.event.pull_request.head.sha }} } # checks out PR code - run: npm install && npm run build # runs untrusted code with write tokens + secrets
Quiz
Completed
Why is this workflow dangerous, and what is the first fix?
Heads-up pull_request_target intentionally runs in the trusted base context with secrets; combining it with a checkout of PR head code and write permissions is the classic exploit pattern, not a recommendation.
Heads-up Pinning actions by SHA is good hygiene, but the dominant risk here is executing untrusted PR code with write-scoped secrets — a far larger blast radius than a tag.
Heads-up Audit catches known advisories; it does nothing about untrusted code running with a write token and secrets. The fix is least-privilege scoping and not granting secrets to untrusted-code runs.
Recap
Every supply-chain review is read in manifests and pipeline YAML: caret ranges plus npm install let new or tampered bytes in, while a committed lockfile plus npm ci enforces exact versions and integrity hashes; cosign verify against an expected build identity, with the image pinned by digest, rejects impostor artifacts at the deploy gate; and a CI workflow that runs untrusted PR code with write-scoped secrets is the highest-blast-radius bug of all. Read the config, find where untrusted bytes or untrusted code meet your credentials, and fix that boundary before adding more scanning.