Getting Started with Artifact Firewall

Block vulnerable and freshly published NPM packages before they ever reach your builds using Varnish’s auto-generated OSV ruleset and a single Docker command.

This tutorial walks you through 3 steps:

  1. Create a configuration file.
  2. Run the container.
  3. Test it with real npm commands.

Prerequisites

  • Docker is installed on your machine.
  • The npm client is installed on your machine.
  • An Artifact Firewall license. Request a trial license if you do not have one.

Step 1: Create your configuration file

Create a project folder with a config/ folder inside it. Put your license in config/license.lic, and add a file called config/default.yaml:

firewall:
  registries:
  - name: npmjs
    remote_url: https://registry.npmjs.org
    routes:
    - host: localhost
  default_action: allow
  default_quarantine_days: 7
  rulesets:
  - git:
      name: osv-npm
      url: https://github.com/varnish/osv-rules.git
      sub_path: rulesets/npm/all.yaml

license:
  file: /etc/varnish-artifact-firewall/license.lic

The registries entry sends every request for the host localhost on to the public npm registry. Two things power the firewall here:

  • rulesets.git pulls the auto-generated OSV ruleset from Varnish’s public repo, refreshed every hour. Every NPM vulnerability in the OSV database becomes a firewall rule, with no manual maintenance.
  • default_quarantine_days: 7 hides any package version published in the last 7 days from latest resolution, giving you a buffer against newly-published malicious packages before they get a chance to spread.

Step 2: Run the container

From your project folder, run:

docker run --rm -p 6089:6089 --name firewall \
  -v ./config:/etc/varnish-artifact-firewall:ro \
  varnish/artifact-firewall
Flag Purpose
-p 6089:6089 Exposes the firewall on port 6089
-v ./config:/etc/varnish-artifact-firewall:ro Mounts your configuration file and license where the firewall reads them (read-only)

You should see the firewall verify the license and load the OSV ruleset, then start serving a few seconds later. The key lines to look for:

time=... level=INFO msg="starting Artifact Firewall" version=0.9.0 ... deployment=standalone mode=normal
time=... level=INFO msg="license verified" company=... expires=...
time=... level=INFO msg="loaded rulesets" default_action=allow rulesets=1 rules=230471 exact_selectors=226179 pattern_selectors=0
time=... level=INFO msg="serving proxy" address=[::]:6089 deployment=standalone

The rules=230471 figure is the full set of npm vulnerability rules from the OSV database, every npm advisory becomes a firewall rule. Your number may differ slightly since the ruleset is regenerated hourly.

Step 3: Test it

In a new terminal, point npm at the firewall by setting it as the default registry:

export NPM_CONFIG_REGISTRY=http://localhost:6089/

This way you don’t need to append --registry=... to every npm command. The --dry-run flag means nothing is installed, while npm still resolves the package and fetches its tarball through the firewall. The --prefer-online flag makes npm ask the firewall again rather than answer from its own cache.

Allowed package

A package with no known vulnerabilities resolves normally:

npm --verbose pack minimist --dry-run --prefer-online
npm http fetch GET 200 http://localhost:6089/minimist 359ms (cache miss)
npm http fetch GET 200 http://localhost:6089/minimist 39ms (cache revalidated)
npm http fetch GET 200 http://localhost:6089/minimist/-/minimist-1.2.8.tgz 36ms (cache miss)
npm notice 📦  minimist@1.2.8
...

The firewall writes an audit log entry for each decision to its standard output, in the terminal that runs the container. The tarball download reads:

{"id":"01a1abe6-91f3-7dee-977e-bee510cdd2f6","ts":"2026-11-05T13:29:37.011Z","kind":"download","purl":"pkg:npm/minimist@1.2.8","rule_id":"default","ruleset_id":"default","action":"allow","enforced_action":"allow","registry":"npmjs","mode":"normal","outcome":"served"}

OSV rules in action: vulnerable versions silently skipped

lodash has several known CVEs in older versions. When you ask for lodash without specifying a version, the firewall transparently steers you to the latest safe version:

npm --verbose pack lodash --dry-run --prefer-online
{"id":"01a1abe6-93c7-74f9-a4c4-86b3ddb229ab","ts":"2026-11-05T13:29:37.479Z","kind":"download","purl":"pkg:npm/lodash@4.18.1","rule_id":"default","ruleset_id":"default","action":"allow","enforced_action":"allow","registry":"npmjs","mode":"normal","outcome":"served"}

The exact version may differ depending on what’s currently latest on npmjs.com/package/lodash; the firewall steers your unpinned install to the highest version not flagged by OSV. As long as the action is allow and the rule_id is default, the OSV ruleset is working as intended. Just before it, a listing entry names each flagged version of the packument, in its decisions.

If you explicitly pin to a vulnerable version, the audit log shows it was matched by an OSV rule:

npm --verbose pack lodash@4.17.20 --dry-run --prefer-online
{"id":"01a1abe6-95d6-71a1-9c50-bfc4b5246de0","ts":"2026-11-05T13:29:38.006Z","kind":"download","purl":"pkg:npm/lodash@4.17.20","rule_id":"GHSA-29mw-wpgm-hmr9","ruleset_id":"osv-npm","action":"hide","enforced_action":"hide","registry":"npmjs","mode":"normal","outcome":"served"}

The rule_id is a real GHSA identifier, look up the CVE details on osv.dev. Every rule in the osv-npm ruleset links back to its origin advisory this way.

By default, OSV severity scores below the deny threshold map to hide: the version stays installable if pinned, but is excluded from latest. To turn hide into a hard 403 block, lower the deny threshold (see the Firewall Configuration Reference) or add a custom action: deny rule, as described in Writing Custom Firewall Rules.

Quarantined: recently-published versions

With default_quarantine_days: 7, any version published in the last 7 days is hidden from latest resolution. Developers running npm install <pkg> get the latest non-quarantined version automatically, protecting against typo-squatting and newly-published malicious packages that haven’t been flagged yet by OSV.

Quarantine is applied when the packument is filtered. A version held back appears in the audit log among the decisions of that packument’s listing entry, with effect set to quarantined.

Next steps


®Varnish Software, Wallingatan 12, 111 60 Stockholm, Organization nr. 556805-6203