The Artifact Firewall is published as a Docker image and a Helm chart, which run it in one of two deployment modes:
standalone, the default: in front of one or more package registries. Clients point at the firewall, which routes each request to one of the configured registries. It filters manifests and refuses blocked downloads, and streams package bodies through without caching them.integrated: as part of a Virtual Registry, which routes and caches. The Virtual Registry fetches manifests through the firewall, and asks it before serving each artifact, from the cache or not.The firewall is also bundled with the Virtual Registry, in its image and packages.
The image is varnish/artifact-firewall on Docker Hub, for linux/amd64 and linux/arm64. It reads its configuration from /etc/varnish-artifact-firewall/default.yaml, and the proxy listens on port 6089.
Put the configuration file and the license in a directory:
# config/default.yaml
firewall:
registries:
- name: npmjs
remote_url: https://registry.npmjs.org
routes:
- host: npm.example.com
rulesets:
- git:
name: osv
url: https://github.com/varnish/osv-rules.git
sub_path: rulesets/npm/all.yaml
license:
file: /etc/varnish-artifact-firewall/license.lic
Then mount the directory in place of the image’s own:
docker run --rm -p 6089:6089 \
-v ./config:/etc/varnish-artifact-firewall:ro \
varnish/artifact-firewall
A client that reaches the firewall as npm.example.com is routed to the npm registry:
npm install express --registry=http://npm.example.com:6089/
With the directory mounted rather than the file, the firewall sees an edited file even when the editor replaced it, so that it can reload it.
The container runs as the unprivileged user varnish, uid and gid 999. The firewall’s own files, such as the Git clones of its ruleset sources or storage.path, have to be under /var/lib/varnish-artifact-firewall, the default work_dir, or on a volume writable by that user.
The Helm chart deploys the firewall on Kubernetes. It is published as oci://registry-1.docker.io/varnish/artifact-firewall-chart, on a version series of its own, and installing it from there takes Helm 3.8 or later. Store the license as a secret:
kubectl create secret generic artifact-firewall-license \
--from-file=./license.lic
Then install the chart with a values.yaml such as:
config:
license:
secret: artifact-firewall-license
firewall:
registries:
- name: npmjs
remote_url: https://registry.npmjs.org
routes:
- host: npm.example.com
helm install -f values.yaml artifact-firewall \
oci://registry-1.docker.io/varnish/artifact-firewall-chart
Everything under config is written to the firewall’s configuration file. The chart’s own values, and how to set up rulesets, storage, probes, the admin API and metrics with it, are in its README:
helm show readme oci://registry-1.docker.io/varnish/artifact-firewall-chart
A Virtual Registry can integrate a firewall that runs on its own, for the registries that set enable_firewall. Varnish fetches their manifests through the firewall, which filters each one before Varnish caches it. Before serving an artifact, from its cache or not, Varnish asks the firewall’s admin API whether the version is allowed. The Virtual Registry keeps routing and caching.
The firewall has to run with deployment: integrated, since it relies on headers added to each request by the Virtual Registry, and both its listeners have to be reachable from Varnish:
firewall:
deployment: integrated
port: 6089
api_address: 0.0.0.0:6090
webhook:
url: http://vr.example.com/purgez
method: PURGE
headers:
Cache-Tags: resource_manifest
rulesets:
- git:
name: npm-osv-rules
url: https://github.com/varnish/osv-rules.git
sub_path: rulesets/npm/all.yaml
address names one.api_address binds loopback by default, so it has to be set. The admin API has no authentication, so keep both ports reachable from the Virtual Registry’s nodes only.webhook purges the manifests cached by Varnish under the previous ones. Point it at the Virtual Registry’s /purgez as above, and add the firewall’s address to purge.allow, which otherwise refuses a purge from anywhere but the node itself. The webhook takes one URL, so a firewall serving several Virtual Registry nodes needs it to point at something that sends the purge on to each of them, such as a Varnish Broadcaster.deployment: integrated the firewall reads no license and sets up no OpenTelemetry, so it exports no metrics or traces, and audit_log_output: otel writes nothing. Give it a JSON audit_log_output such as stdout or a file.The Virtual Registry names the firewall’s two listeners in the firewall section of its own configuration:
virtual_registry:
registries:
- name: npmjs
enable_firewall: true
remotes:
- url: https://registry.npmjs.org
firewall:
remote_address: firewall.example.com:6089
remote_api_address: firewall.example.com:6090
With remote_address set, the Supervisor starts no firewall of its own and ignores the rest of its firewall section. Its license still needs the sup-firewall and sup-auth addons.
remote_addressType: String
Address of the firewall’s proxy, in host:port form. Every registry that sets enable_firewall uses it, and Varnish sends it the manifests to filter. It has to be set together with remote_api_address, and cannot be combined with address.
remote_api_addressType: String
Address of the firewall’s admin API, its api_address, in host:port form. Varnish calls /api/eval there to authorize each artifact download. It has to be set together with remote_address.
The Virtual Registry’s image and packages also carry the firewall. The Supervisor runs it in its own process, under deployment: integrated. The firewall reads the firewall section of the Supervisor’s configuration file, beside the Virtual Registry’s own sections:
varnish:
http:
- port: 80
virtual_registry:
registries:
- name: npmjs
default: true
enable_firewall: true
remotes:
- url: https://registry.npmjs.org
firewall:
default_action: allow
rulesets:
- git:
name: npm-osv-rules
url: https://github.com/varnish/osv-rules.git
sub_path: rulesets/npm/all.yaml
license:
file: /etc/varnish-supervisor/license.lic
The rest belongs to the Supervisor as well:
sup-firewall and sup-auth addons.otel section, as described under Metrics and tracing.firewall section takes effect when the Supervisor restarts.