Artifact Firewall 0.4.0

Released: 2026-07-31

Added

  • Warn when the firewall starts or reloads with no rulesets configured, since it then falls back to applying only the default action to all traffic.
  • Git ruleset sources can now authenticate to GitHub with a GitHub App via auth.github_app (a client ID and a private key by path or env). The firewall discovers the App installation from the repository URL, then mints and refreshes short-lived installation tokens automatically. api_base_url supports GitHub Enterprise Server.
  • Added Hex (Erlang/Elixir) support, including JFrog Artifactory’s Hex repository prefix. Hex’s package manifest (/packages/<name>) is a signed protobuf payload that the client cryptographically verifies, so unlike PyPI/NuGet/Maven, denied or vulnerable versions can’t be filtered out of it (any change to the payload breaks the signature and hex_core rejects the response outright); enforcement is instead a per-tarball allow/deny check on download.
  • OpenTelemetry metrics exporter configured via a top-level otel: block whose schema matches Varnish Supervisor’s, so the same config works standalone or integrated. otel.metrics.exporter selects otlp (push) or prometheus (scrape). Standalone stands up its own OTel SDK. Integrated reuses Supervisor’s MeterProvider, where firewall metrics appear under instrumentation scope artifact-firewall.
  • OpenTelemetry tracing over OTLP, configured under otel.tracing (off until enabled with an endpoint). Per request the firewall emits an HTTP server span, a firewall.proxy span, a firewall.transform_manifest span, and an upstream client span. The admin /api/eval endpoint emits a firewall.evaluate span with the rule decision. Inbound W3C traceparent headers are honored and propagated upstream. Standalone stands up its own TracerProvider. Integrated reuses Supervisor’s.
  • Audit log export over OpenTelemetry logs. Set audit_log_output: otel to export the audit log through the OTel logs pipeline (configured under otel.logs) instead of JSON. Each entry becomes an OTel log record under its own scope artifact-firewall/audit (fields as attributes, severity by action), correlated with the request trace. Standalone stands up its own LoggerProvider. Integrated reuses Supervisor’s.
  • Process log export over OpenTelemetry logs. Set log_output: otel to export process logs through the OTel logs pipeline under scope artifact-firewall/log. This tees to stderr (startup logs are never lost) and also exports to OTel. log_output is now honored generally (stdout by default, stderr, or a file path), having previously been ignored. File-based process logs are closed on shutdown and reopened on SIGHUP for external rotation, matching the audit log.

Changed

  • Metrics are now configured under otel.metrics instead of the top-level metrics_address. otel.metrics.exporter selects otlp (default, push) or prometheus (scrape endpoint at prometheus_host:prometheus_port, default localhost:9464). In integrated mode the firewall reuses Supervisor’s metrics pipeline.
  • Replacing metrics_address: ":9090" takes two settings: an endpoint or exporter: prometheus, since metrics are no longer exported by default, and prometheus_host: "0.0.0.0", since the scrape endpoint now binds loopback only.
  • The firewall warns at startup when a signal is enabled with nowhere to export: metrics or tracing without an endpoint, or audit_log_output/log_output set to otel without otel.logs.
  • The metrics_address config field is deprecated and inert: it still parses (logging a warning) but has no effect. Configure metrics under otel.metrics.

Fixed

  • Maven: a denied version no longer breaks resolution for packages that are allowed. Maven reads the .pom of every candidate version while resolving version conflicts, including versions it then discards, so returning 403 for a denied .pom failed the whole resolve. .pom files (and Gradle’s .module) now stream through unchanged, and a deny is enforced on the artifact itself whatever its packaging type, so a build that pins a denied version still gets a 403.
  • Maven artifacts and manifests served through a JFrog Artifactory repository are now correctly identified, filtered, and rewritten.
  • Fixed a race between a git ruleset fetcher rewriting its file and a reload reading it, which could intermittently fail a reload with a misleading YAML parse error.
  • The environment variable named by a git ruleset’s auth.token_env is no longer passed to git subprocesses, where the token was readable through /proc/<pid>/environ and by anything git spawned (credential helpers from a system gitconfig, pagers, filters). The token still reaches the remote as an HTTP header.
  • A failed audit log reopen on SIGHUP no longer leaves audit logging dead until restart: the new file is opened before the old one is closed, so a failure keeps the existing file in use.
  • Closing the audit log no longer races a SIGHUP arriving during shutdown, which could close one file descriptor twice and leak the other.

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