How it works

Chainsaw is a firewall for your package installs.

Every npm install, pip install, docker pull runs through a policy engine before it touches the registry. Allow it (cached), or block it with a clear error. Watch one of each below.

  • npm install
  • lockfiles
  • CI jobs
  • IDE tooling
  • registry auth

What changes for developers: almost nothing. No SDK, no laptop agent, no CI plugin. The only difference is that bad packages fail with a message telling them why.

Why this exists

Supply-chain attacks don't look like CVEs.

event-stream, ua-parser-js, xz-utils, and the March 2025 tj-actions/changed-files GitHub Action compromise all shipped to developer machines before any vulnerability scanner caught them. A post-hoc SCA finds the bad package after it's on disk — sometimes after it's already run a postinstall script. Chainsaw blocks these at install time, on rules you can read and change.

From npm install to package-on-disk

Three phases: set it up once, run every install through it, roll it out without breaking builds.

01

Setup · one-time

Point one URL at Chainsaw

Change one registry URL in the config your package manager already reads. Nothing else changes — no SDK, no laptop agent, no CI plugin, no new build step.

~/.npmrc
// before
registry=https://registry.npmjs.org/
// after
registry=https://your-org.chain305.com/npm/

Same pattern for pip.conf, settings.xml, Dockerfile FROM lines, NuGet, Cargo, Go, Composer, APT — one URL per ecosystem. See the per-ecosystem guides →

02

Every install · runtime

Policy evaluates, then allow or block

On every request, Chainsaw evaluates the package in parallel against your rules — low single-digit milliseconds — before forwarding to the upstream registry or returning an error.

Allow path
  • Rules pass in parallel: vulnerability gates, licenses, versions, provenance (who published it, signed by whom), plus up to 12 supply-chain attack signals depending on the ecosystem.
  • Package streams back through the content-addressed cache (deduped by hash — the second install of the same version is faster than upstream).
  • Developer sees the usual added 1 package. Chainsaw is invisible.
Block path

The developer sees the exact rule that fired, in their own terminal:

$ npm install log4j-core@2.14.1
npm ERR! Chainsaw: blocked
npm ERR!   rule:    block-critical-vulns
npm ERR!   reason:  CVE-2021-44228 (CVSS 10.0, EPSS 0.97)
npm ERR!   contact: security@your-org.com

EPSS is the likelihood of real-world exploitation — it filters out the long tail of "technically a CVE, nobody exploits it" noise.

What rules run on every request

Six rule families

  • Vulnerability gates — CVE, CVSS, EPSS, KEV
  • Licenses — SPDX allowlist/denylist per ecosystem
  • Versions — pinned, semver windows, release-age floors
  • Provenance — signed builds, trusted publishers
  • Client context — who's installing, from where, into what
  • Exceptions — reviewed, dated, scoped overrides

Up to 12 supply-chain attack signals

  • Install-script exfiltration (npm / pip / rubygems / cargo / composer)
  • Maintainer-account takeover (npm / pip / rubygems / nuget / maven / gradle)
  • Publish-velocity bursts (npm / pip / rubygems / nuget)
  • Hidden characters in package (source-archive ecosystems)
  • Typosquat across 14 ecosystems (not APT / Yum / DNF)
  • Version anomalies (every SemVer ecosystem)
  • Reserved-namespace dependency confusion (universal)
  • Container-image malware feed (Docker)
  • Per-layer image enforcement (Docker)
  • OS-package hash-chain provenance (APT / Yum / DNF)
  • Repo liveness + ownership match (trust-score input)
  • Checksum fail-closed enforcement (npm / pip / rubygems / composer / maven / gradle / nuget / cargo)
03

Rollout · ongoing

Monitor first, enforce when ready, prove it afterward

Every rule ships with a monitor mode: the decision is recorded, but the install still succeeds. You see exactly what would have been blocked across every repo and pipeline, add exceptions where needed, then flip the rule to enforce — per rule, per repo, per team.

policy.yaml
rule: block-critical-vulns
match:
  cvss: ">= 9.0"
  epss: ">= 0.5"
mode: monitor  # week 1–2: just record what would fire
mode: enforce  # week 3+: block the install

Every allow/block is logged with timestamp, user, rule, and package metadata. Export a CycloneDX SBOM (standard file that lists everything you shipped) per repo, stream the audit log to your SIEM, or roll a policy back from the dashboard — no developer workstation touched.

When things go wrong

Three failure modes, three answers. Your builds don't break.

  • Chainsaw down: enforce mode serves cache; monitor mode fails open.
  • Upstream down: cache serves previously-allowed installs.
  • Rule too aggressive: one-click exception with reviewer, reason, expiry.

Chainsaw itself is down

In monitor mode, Chainsaw fails open with an audit record — installs never break. In enforce mode, the default is fail-closed, but you can flip to fail-open with cache-only fallback per policy. The cache continues to serve previously-allowed installs during a full outage.

The upstream registry is down

npm, PyPI, or Docker Hub having a bad day doesn't block your builds. Cached versions serve from Chainsaw's content-addressed blob store. Only packages you haven't installed before fail, and they fail with the upstream's own error — not ours.

A rule is too aggressive

A blocked legitimate install is one click away from an exception. The exception carries a reviewer, a reason, and an expiry date. The reviewer dashboard queues the request; the developer sees a structured error naming the rule and the exception contact. No escalation to platform-eng needed.

Still skeptical? Start in monitor mode. Every rule supports it out of the box — we log the decision but still let installs through, so you can measure exactly what would have been blocked across every repo and pipeline before you enforce a single thing.

Read the getting-started guides →

Ready to roll out?

Put Chainsaw on the install path

Start free, switch to blocking when you're ready, or chat with us about custom deployments.