Artifact Firewall 0.9.0

Released: 2026-11-04

Added

  • A standalone firewall reloads its config file on SIGHUP and when the file changes on disk (config_watch, ARTIFACT_FIREWALL_CONFIG_WATCH), without a restart. A reload is all or nothing. A change to a field that needs a restart, such as port, otel, log_output or a git or http ruleset source, refuses it, and the firewall keeps running the config it had. The systemd unit gets ExecReload, so systemctl reload works. SIGHUP also rebuilds the rules, so it applies an edited ruleset file, and one that finds the rulesets unchanged, as from log rotation, leaves the rules and caches alone and sends no webhook. An embedder applies a new firewall config with Firewall.Reconfigure.
  • VS Code Marketplace (vscode-extension) is now a supported ecosystem. Unlike the other ecosystems, deny keeps an extension listed and refuses its download, and hide removes it from listings. A VS Code deployment needs HTTPS and a raised max_manifest_size.
  • firewall.redirects.signing (enabled, key_env, url_ttl) signs metadata the firewall embeds in rewritten URLs, so a client cannot alter or replay it.
  • Downloads refused at preflight are now counted in firewall_requests_total, in every ecosystem. New audit fields block_reason and substituted_with. See docs/audit-log.md.
  • A JSON Schema for the config file, printed by the new -schema flag, for editors and tooling to check a config before the firewall reads it.
  • A JSON Schema for ruleset files, pkg/rulesetschema/ruleset.schema.json.
  • -validate-rulesets <path>... checks ruleset files without starting a firewall, reports every problem and exits non-zero if there is one.
  • The Docker image is built for linux/arm64 as well as linux/amd64.
  • The Docker image is published on DockerHub as varnish/artifact-firewall.
  • rulesets[].http fetches rulesets from a zip or tar archive over HTTP(S), such as an S3 object, and picks them out with sub_path/sub_paths as a git source does. It polls with conditional requests (ETag/Last-Modified), so an unchanged archive is not downloaded again, also after a restart.
  • boot_path on a git or http ruleset source names local rulesets to start on, so startup no longer waits on the remote, and a firewall whose remote is unreachable still starts. They are used until the first successful sync, unless a cache from an earlier run is there.
  • A Helm chart for a standalone firewall, published on DockerHub as varnish/artifact-firewall-chart on a version series of its own, with its own changelog. helm show readme oci://registry-1.docker.io/varnish/artifact-firewall-chart prints its documentation.

Changed

  • Manifests are parsed once instead of twice, which cuts the CPU spent transforming them. A manifest with anything but whitespace after its JSON value is now refused as malformed; it used to be read up to the end of the first value.
  • A ruleset with a qualifier in a purl, such as pkg:maven/org.example/lib?classifier=sources, now fails to load. Qualifiers were ignored, so that rule matched every artifact of lib.
  • A config that conflicts with itself is refused with a message naming the setting, e.g. firewall.rulesets[]: set exactly one of path, git or http. An unknown default_action is now refused with the other config errors at startup.
  • The packaged default config (/etc/varnish-artifact-firewall/default.yaml) sets deployment: standalone and carries a commented example registry to start from.
  • The Docker image runs as the unprivileged varnish user, uid and gid 999. Anything the firewall writes must be under /var/lib/varnish-artifact-firewall or a volume that user can write.
  • A git ruleset source accepts sub_path: ., the root of the repository. Like any directory, it takes every ruleset under it, so rulesets at the root no longer have to be listed one by one. A directory sub path now leaves out hidden files and directories under it, such as .github/, unless the sub path names them.

Fixed

  • Fixed rules not matching Maven Central artifacts requested below /maven2, the path Maven Central serves its repository at, so denied versions downloaded. The groupId was read with maven2. in front. /maven2 is now recognized like a repository manager prefix, in both deployment modes, as the Virtual Registry already does.
  • Fixed PyPI downloads from a https://pypi.org remote looping back through the Virtual Registry’s own hostname. The JSON simple index pointed every file URL at the base URL, although pypi.org serves its files from files.pythonhosted.org, so a download was fetched from the Virtual Registry itself and then redirected by pypi.org, and it failed wherever the Virtual Registry cannot reach its own hostname. Behind Virtual Registry, a file URL on another host than the remote’s is now left as it is, and Virtual Registry routes it through /redirectz, as it already did for the HTML index. A standalone firewall still rewrites it.
  • Fixed -version in the Docker image reporting the revision with -dirty appended, although the image was built from a clean commit.
  • Fixed a manifest the firewall rewrites failing to parse when the client offered an encoding the firewall cannot decompress, such as br from VS Code. Such manifests are now requested with Accept-Encoding: gzip.
  • A git ruleset named . or .. is now refused at startup. Its cache directory resolved to the shared git cache or to work_dir itself, which the firewall could delete when it discarded an unusable cache.
  • A git ruleset’s fetch_timeout now stops a stalled fetch over HTTP(S). Only git itself was killed, so its remote helper kept running and the sync went on until the remote gave up, however short the timeout.
  • Fixed a rule disabled through the admin API coming back enabled after the second ruleset reload, a rule enabled there despite disabled: true in its ruleset coming back disabled after the first, and a change made there while a reload was running being lost.
  • Fixed RPM and conda clients getting a package list filtered under a rule’s old status after the rule was enabled or disabled through the admin API, until the next ruleset reload or mode change.
  • Fixed a disabled rule that denies a whole package still blocking it. Whether disabled in its ruleset or through the admin API, the rule was skipped when versions were filtered but still refused the request for the package’s metadata.

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