# Lockfile committed to repo

- **Pattern:** `ab-002138` (`code-quality-essentials.type-safety.lockfile-committed`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002138
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002138)

## Why it matters

A missing lockfile means `npm install` resolves dependency versions at install time rather than pinning them. Two developers on the same project — or the same developer on two machines — can get different dependency trees. CWE-1357 and SLSA L1 both identify non-deterministic builds as a supply-chain risk: a transitive dependency can silently introduce a breaking change or a security regression between developer and CI, making bugs impossible to reproduce. SSDF SP 800-218 PW.4.1 requires reproducible builds as a baseline software security practice.

## Severity rationale

High because non-deterministic installs make bugs non-reproducible between environments and open the door to transitive dependency drift introducing security vulnerabilities undetected.

## Remediation

Run your package manager's install command to generate the lockfile, then commit it and keep it committed. Remove the lockfile from `.gitignore` if it appears there.

```bash
npm install          # generates package-lock.json
git add package-lock.json
git commit -m "chore: add lockfile for reproducible installs"
```

In CI, always use `npm ci` instead of `npm install` — `npm ci` installs exactly from the lockfile and errors if it diverges from `package.json`. For Yarn or pnpm, use `--frozen-lockfile`.

## Detection

- **ID:** `lockfile-committed`
- **Severity:** `high`
- **What to look for:** Check the project root directory for any of: `package-lock.json` (npm), `yarn.lock` (Yarn v1 or v2/v3), `pnpm-lock.yaml` (pnpm), `bun.lockb` (Bun). Also check `.gitignore` to confirm the lockfile is not being excluded from version control. A missing lockfile means each `npm install` may resolve different package versions, making bugs impossible to reproduce deterministically between developer machines and CI.
- **Pass criteria:** Enumerate all relevant code locations. A lockfile for the detected package manager is present in the project root and not excluded by `.gitignore` with at least 1 verified location.
- **Fail criteria:** No lockfile exists, or a lockfile exists but is listed in `.gitignore`. A partial implementation does not count as pass.
- **Skip (N/A) when:** Project is not a Node.js/JavaScript project (no `package.json`).
- **Cross-reference:** Compare with `code-quality-essentials.dependencies.build-reproducible` — the lockfile (this check) enables reproducible builds; the build check verifies the full CI pipeline.
- **Detail on fail:** `"No lockfile (package-lock.json / yarn.lock / pnpm-lock.yaml) found in repository root; dependency resolution is non-deterministic"`
- **Remediation:** Run your package manager's install command to generate the lockfile, then commit it:

  ```bash
  npm install          # generates package-lock.json
  git add package-lock.json
  git commit -m "chore: add lockfile for reproducible installs"
  ```

  If you find the lockfile in `.gitignore`, remove that entry. For CI, always use `npm ci` (or `yarn install --frozen-lockfile` / `pnpm install --frozen-lockfile`) to install from the lockfile without resolving new versions.

## External references

- cwe CWE-1357
- slsa L1
- ssdf PW.4.1

Taxons: supply-chain

HTML version: https://auditbuffet.com/patterns/ab-002138
