A Git-native dependency admission controller. Evaluates trust signals on every dependency change.
trustlock runs as a Git pre-commit hook (advisory mode) and a CI check (enforce mode):
- Advisory (pre-commit): warns on violations, exits 0, advances the trusted baseline when all packages are admitted.
- Enforce (
--enforce): blocks on violations, exits 1, never advances the baseline.
Trust signals evaluated per-package:
- Cooldown — how long since the version was published to the registry
- Provenance — whether the package has SLSA attestations
- Pinning — whether the lockfile uses exact versions
- Install scripts — whether the package runs install-time scripts
- Sources — whether the package comes from the registry, a git URL, a local path, or a URL
- New dependencies — first-time additions to the project
- Transitive surprise — unexpected jump in transitive dependency count
- Publisher change — whether the package's publisher identity changed between versions
npm install -g trustlockRequires Node.js >= 18.3.
| Lockfile | Ecosystem | Versions |
|---|---|---|
package-lock.json |
npm | v1, v2, v3 |
pnpm-lock.yaml |
pnpm | v5, v6, v9 |
yarn.lock |
yarn | classic (v1), berry (v2/v3) |
requirements.txt |
Python (pip) | — |
uv.lock |
Python (uv) | — |
# 1. Initialize trustlock in your project
trustlock init
# 2. Install the Git pre-commit hook
trustlock install-hook
# 3. Optionally review your current dependency posture
trustlock auditAfter init, trustlock creates:
.trustlockrc.json— policy configuration.trustlock/baseline.json— trusted dependency snapshot.trustlock/approvals.json— approval records.trustlock/.cache/— registry cache (gitignored)
Commit .trustlockrc.json and .trustlock/baseline.json to your repository.
# Run dep install as normal
npm install lodash@4.17.21
# trustlock check runs automatically via the pre-commit hook.
# To run it manually:
trustlock check
# Output when all packages are admitted:
# ✔ lodash@4.17.21 — admittedWhen all packages pass, trustlock check advances the baseline automatically (advisory mode only) and exits 0.
# A new package fails the cooldown rule:
trustlock check
# ✖ new-hotness@1.0.0 — blocked
# exposure:cooldown Published 2h ago (policy requires 72h)
# Run to approve: trustlock approve new-hotness@1.0.0 --override cooldown --reason "..." --expires 7d
# Approve the override, then re-check:
trustlock approve new-hotness@1.0.0 \
--override cooldown \
--reason "Needed for feature X; verified safe by team review" \
--expires 7d
trustlock check
# ✔ new-hotness@1.0.0 — admitted with approval# Detect version drift and provenance inconsistencies across monorepo packages
trustlock audit --compare packages/frontend packages/backend packages/shared| Command | Description |
|---|---|
trustlock init |
Initialize trustlock in the current project |
trustlock check |
Evaluate dependency changes against policy |
trustlock approve <pkg>@<ver> |
Approve a blocked package |
trustlock audit |
Scan the full dependency tree for trust posture |
trustlock audit --compare <dir...> |
Compare dependency posture across multiple projects |
trustlock clean-approvals |
Remove expired approval entries |
trustlock install-hook |
Install the Git pre-commit hook |
trustlock ships two built-in profiles selectable with --profile:
| Profile | Effect |
|---|---|
strict |
168h cooldown, provenance required for all packages |
relaxed |
24h cooldown, no block on provenance regression or publisher change |
# Use strict profile in CI
trustlock check --enforce --profile strictTeams can centralize policy in a shared URL and extend it per repo:
{
"extends": "https://policy.example.com/trustlockrc.json",
"cooldown_hours": 96
}Repo configs can only tighten org policy — floor enforcement prevents repos from reducing org-mandated thresholds.
- USAGE.md — Full command reference, all flags, exit codes, error messages
- POLICY-REFERENCE.md — Every
.trustlockrc.jsonoption - ARCHITECTURE.md — Design decisions and module map
- examples/ — Config and CI workflow examples
Add trustlock to your CI pipeline:
# GitHub Actions — see examples/ci/github-actions.yml
- run: npx trustlock check --enforceSee examples/ for GitHub Actions, Lefthook, and Husky configurations.
##Where trustlock sits in the timeline
Trustlock evaluates lockfile changes at commit time. It doesn't intercept or sandbox npm install. If a malicious package runs a postinstall script, that executes before trustlock sees it. Trustlock prevents the compromised lockfile from being committed and merged, containing blast radius to a single developer machine instead of the entire team and production. For install-time script blocking, use --ignore-scripts or pnpm's default lifecycle script controls.
- Not a malware scanner — trustlock does not inspect package source code or detect known-malicious signatures. Use a dedicated scanner for that.
- It's not an install-time sandbox - trustlock doesn't intercept npm install. Use --ignore-scripts for that.
- Not a CVE tracker — use
npm auditor Snyk for vulnerability databases. - Not a license checker — use
license-checkeror similar. - Not a replacement for pnpm trustPolicy or npm's min-release-age — those are server-side controls enforced by the registry. trustlock is a client-side admission gate at the repo boundary.
trustlock was built out of frustration with how passive the standard Node.js toolchain is about what actually gets pulled into a project. npm install will fetch anything — a package published two minutes ago, one that runs arbitrary scripts at install time, one that swapped from a registry tarball to a git URL overnight — and the only feedback you get is a lockfile diff.
The threat model trustlock addresses is narrow but real: the window between when a malicious version is published and when it is pulled or flagged. Vulnerability scanners operate after the fact. trustlock operates at the admission point, before anything lands in your repo or your CI.
The design is intentionally minimal. trustlock has no runtime dependencies — it is itself a zero-supply-chain-risk tool. It does not replace a vulnerability scanner or a dependency audit; it enforces trust continuity. Once a version is in your baseline, it is trusted. Anything new has to earn admission against the policy you declare.
The approval workflow exists for teams that need an escape hatch without losing auditability. Every override is timestamped, scoped to specific rules, and expires. clean-approvals is a first-class command, not an afterthought.
