Dependency freshness & install-script governance for modern package ecosystems. Reduce exposure to short-lived malicious releases without disrupting developer workflow.
Modern supply-chain attacks against npm, PyPI and friends increasingly rely on the gap between publication and detection: a maintainer is compromised, a poisoned patch ships, CI installs it within minutes, secrets exfiltrate, and the version is withdrawn before traditional scanners notice.
CVE databases and malware signatures are necessary but reactive. They detect known compromise — they don't reduce exposure to emerging compromise.
InstallGuard takes a different angle:
- Wait before adopting brand-new package versions.
- Approve which packages may run install-time scripts.
- Block dependencies from exotic sources (Git URLs, tarballs, GitHub shortcuts).
- See dependency risk at PR time, not after a breach.
- Prove which policy a build was governed by, via signed attestation.
Sometimes the best supply-chain defence is simply waiting 24 hours before installing something.
Read the full argument in the whitepaper.
Status legend: ☑ shipped · ◐ partial · ☐ planned
| Capability | Status |
|---|---|
Lockfile adapters: package-lock.json, pnpm-lock.yaml, yarn.lock (Berry) |
☑ |
| Minimum release-age enforcement (per environment, with direct-dep overrides) | ☑ |
Lifecycle script approval lists (preinstall / install / postinstall) |
☑ |
| Exotic-source blocking (Git, tarball, GitHub shortcut) | ☑ |
| Multi-signal detection: publisher change, deprecation, dist-tag churn, file-set diff, account age, typosquat / homoglyph, suspicious-script static analysis | ☑ |
| Trust-score computation with per-signal contribution breakdown | ☑ |
| External signal providers: OSV/GHSA advisories, deps.dev project metadata, OpenSSF Scorecard | ☑ |
Public SignalProvider trait for third-party providers (see crates/core/examples/minimal_provider.rs) |
☑ |
| PR annotations (GitHub Action, GitLab MR widget) + per-PR risk summary | ☑ |
Deterministic installguard.lock + in-toto attestation (policy-evaluation/v1) |
☑ |
| CycloneDX SBOM export with policy-decision properties + per-package VEX | ☑ |
--frozen offline re-verification against a recorded snapshot |
☑ |
| Maintainer 2FA status check | ◐ deferred (registry doesn't expose it unauthenticated) |
| Sigstore signing (cosign keyless / KMS) for attestations | ◐ structural provenance match shipped; full Fulcio/Rekor verification deferred |
| Sandboxed install-script execution | ☐ planned (M5) |
| Registry-proxy enforcement (Verdaccio / Artifactory / Nexus) | ☐ planned (M6) |
| Multi-ecosystem support (PyPI, crates.io, Go, RubyGems, …) | ☐ planned (M7) |
See the roadmap for milestones and the design document for the technical scope.
InstallGuard is complementary, not a replacement, for:
npm audit, Snyk, osv-scanner — keep them; they catch known vulnerabilities.- Dependabot / Renovate — keep them; InstallGuard makes their PRs safer to merge.
- pnpm built-ins (
minimumReleaseAge,onlyBuiltDependencies) — InstallGuard operationalises these across an organisation: central policy, audit, attestation, registry-proxy enforcement.
Comparison table in whitepaper §17.
Alpha —
0.1.0. Pre-built binaries land with the first tagged release; until then both install paths build from source.
# Homebrew (macOS, Linux) — once jt-systems/homebrew-installguard is published:
brew install jt-systems/installguard/installguard
# Or build from source (Rust 1.86+):
cargo install --path crates/cli
# Initialise a baseline policy
installguard init
# Scan the current project (uses package-lock.json / pnpm-lock.yaml / yarn.lock)
installguard scan
# In CI: hard-fail on policy violations and emit an attestation
installguard ci --attestation installguard.intoto.jsonl
# Air-gapped CI: re-verify offline against a recorded snapshot
installguard ci --frozenExternal signal providers (OSV, deps.dev, OpenSSF Scorecard) are on by default and individually opt-out for offline runs:
installguard scan --no-osv --no-deps-dev --no-scorecardExample policy (installguard.yaml):
policyVersion: 1
defaults:
minimumReleaseAge: 1440 # minutes (24h)
blockExoticSubdeps: true
detectPublisherChange: true
flagDeprecated: true
detectVersionSurfaceChange: true
minMaintainerAccountAgeDays: 30
requireProvenance: false # opt-in once your supply chain emits it
maxAdvisorySeverity: high # OSV / GHSA gate
requireLicense: true # deps.dev gate
licenseAllowlist: [MIT, Apache-2.0, BSD-3-Clause, ISC]
blockArchived: true
minScorecardScore: 5 # OpenSSF Scorecard 0-10
minTrustScore: 60
scripts:
policy: deny-by-default
allow: [esbuild, sharp, playwright]
direct:
minimumReleaseAge: 4320 # stricter for direct deps
detectPublisherChange: trueFull DSL in DESIGN.md §4. More examples in examples/policies/ (coming soon).
InstallGuard separates dependency acquisition from script execution:
# npm
npm ci --ignore-scripts && installguard scan && npm rebuild
# pnpm
pnpm install --ignore-scripts && installguard scan && pnpm rebuild
# yarn (Berry)
yarn install --mode=skip-build && installguard scan && yarn rebuildIf anything fails policy, scripts never run.
InstallGuard is in alpha. Milestones 0–4 are shipped: full lockfile coverage for the three major npm package managers, a multi-signal detection model, deterministic decisions with in-toto attestations, three external signal providers (OSV, deps.dev, OpenSSF Scorecard), and a public SignalProvider trait for third-party providers. The next focus areas are sandboxed script execution (M5) and registry-proxy enforcement (M6) — see ROADMAP.md.
If you're interested in early adoption, threat-model review, real-world lockfiles for adapter testing, or contributing rule ideas, please open an issue.
- Whitepaper — the conceptual model, threat model, and standards mapping.
- DESIGN.md — the technical design (architecture, policy DSL, attestation format, performance targets).
- ROADMAP.md — prioritised milestones from foundations through compliance reporting.
- Preventative over reactive. Reduce exposure; don't only chase known IOCs.
- Deterministic and auditable. Every decision is recorded, hashable, and signable.
- Offline-capable by default. No phone-home. Air-gapped deployments are first-class.
- Boring distribution. Single static binary. No
node_modules. No install scripts of our own. - Operationalise existing controls. Don't reinvent pnpm, Sigstore, or OSV — orchestrate them.
- Honest about limits. See whitepaper §20.
See CONTRIBUTING.md for guidelines.
- Issues and discussion are welcome.
- Sanitised real-world lockfiles for adapter golden tests are particularly useful.
- Third-party signal providers: implement the
SignalProvidertrait — seecrates/core/examples/minimal_provider.rsfor a ~30-line worked example. - Security-relevant reports: please follow SECURITY.md rather than opening a public issue.
Licensed under the Apache License, Version 2.0. The Apache-2.0 licence was chosen specifically for its explicit patent grant — important for a security tool intended for enterprise adoption.