Skip to main content

03 - Dependency Pinning and Provenance

Lockfile Hardeningโ€‹

A critical practice in securing your software supply chain is ensuring that builds are reproducible. If npm install installs different sub-dependencies today than it did yesterday, your application's behavior and security posture are unpredictable.

Lockfiles (package-lock.json, yarn.lock, Pipfile.lock, Cargo.lock) store the exact versions and integrity hashes of all installed dependencies.

Best Practices for Lockfiles:โ€‹

  1. Always commit lockfiles to version control.
  2. Enforce deterministic builds. In CI/CD pipelines, ensure the package manager fails if the lockfile is out of sync with the manifest, and doesn't update the lockfile automatically.

NPM: Use npm ci (clean install) instead of npm install in your CI pipelines. npm ci bypasses package.json to install modules directly from the lockfile and throws an error if they are out of sync.

# Good CI practice
npm ci

Python (pip): Use pip-tools or Poetry to manage lockfiles.

# Using pip-tools to generate requirements.txt with hashes
pip-compile --generate-hashes
pip install --require-hashes -r requirements.txt

Rust (Cargo): Cargo always uses Cargo.lock by default. In CI, you can enforce that the lockfile is up-to-date:

cargo build --locked

In-Toto Provenance Attestationsโ€‹

Provenance answers the question: How was this software built, and what inputs were used?

in-toto is a framework to secure the integrity of software supply chains. It allows you to create attestationsโ€”cryptographically signed metadata about the steps performed in the software supply chain.

An in-toto attestation consists of a statement with a predicateType (like SLSA Provenance).

Example SLSA Provenance Payload:

{
"_type": "https://in-toto.io/Statement/v0.1",
"subject": [{"name": "my-app.tar.gz", "digest": {"sha256": "..."}}],
"predicateType": "https://slsa.dev/provenance/v0.2",
"predicate": {
"builder": { "id": "https://github.com/Attestations/GitHubActions" },
"buildType": "https://github.com/Attestations/GitHubActionsWorkflow",
"invocation": {
"configSource": {
"uri": "git+https://github.com/my-org/my-repo@refs/heads/main",
"digest": {"sha1": "..."}
}
}
}
}

Consumers can use tools to verify this attestation before running the software.