BytesafeDependency Firewall

Execution phases

What each execution phase sees during an install, and why filtering versions keeps builds running while download rules are the hard stop.

A rule runs in exactly one execution phase: versions, download, or upload. The phase decides which requests the rule sees, what information it can use, and, most importantly, what a block feels like to the developer on the other end. A versions rule steers the client to an allowed version and the install succeeds; a download rule stops the install. The evaluation pipeline itself is identical in every phase; this page is about what happens around it.

The dashboard rule form labels the versions phase filter versions in the Execution Phase picker, because it is an action like download and upload rather than a noun; download and upload keep their names. The config, API, and CLI use versions. This page uses the config names throughout.

How one install reaches the firewall twice

Package managers separate deciding what to get from getting it. Take a package install as the running example; every supported ecosystem follows the same shape, only the protocol differs (see Ecosystems).

First the client asks for the package's metadata: the list of published versions and tags. It resolves the requested range (or the default tag) against that list, then repeats the process for every dependency in the tree. Only then does it download the artifacts for the versions it settled on. The firewall stands in both request paths, and the two phases map onto them:

Package manager
Firewall
Upstream
versions phase
Version list for a package
Fetch metadata
All versions and tags
versions rules filter the list
Allowed versions only
selects an allowed version, repeats for every dependency in the tree
download phase
Download a resolved package version
Fetch artifact
Artifact
versions rules, then download rules, run on that one version, artifact available for inspection
Artifact served, or an error with package, version, and request ID
Package manager
Firewall
Upstream
request response

The client never sees the firewall as a separate step. It talks to what looks like a registry, and the registry happens to answer according to policy.

The versions phase

A blocking rule in the versions phase steers the client rather than failing it. It removes matching versions from the metadata before the client sees them, along with any tags pointing at them. The client resolves against what remains and lands on the newest allowed version. The install succeeds, the build runs, and with log: true the firewall log still records exactly which versions were filtered and why.

This is the property that makes policies like delaying new versions workable day to day. The policy holds without anyone enforcing it: developers cannot resolve to a version the policy excludes, but they also do not sit blocked waiting for a release to age or an approval to arrive. Work continues on the allowed versions.

Filtering has two boundaries worth knowing:

  • It needs an alternative to exist. An exact pin of a filtered version, or a named tag pointing at one, fails: the client resolves against the filtered metadata and cannot substitute a pinned version.
  • It only knows the metadata. A versions rule can use the package name, the upstream, registry state such as deprecation, and the publish date (maxAgeHours). Anything that requires the artifact itself is out of reach.

Do exact pins or lockfiles bypass the filter?

No, but the two paths fail differently. An exact pin (react@18.2.0) resolves against the filtered metadata, so the client reports the version as not found. A request that skips resolution and fetches the artifact directly, such as a tarball URL taken from a lockfile, is checked against the versions rules at download time instead. That request fails with the same explicit error a download block produces: the package, the version, and a request ID, recorded in the firewall log as a download entry.

Either way, a version removed by a versions rule cannot enter. What differs is the error the developer sees: "this version does not exist" when the client resolved metadata, an explicit block when it went straight for the artifact. Policies that should always fail loudly still belong in download, alone or in addition.

The download phase

A blocking rule in the download phase is a hard stop: there is nothing to steer towards, so the request fails. download rules run when the client fetches an artifact, once per artifact, with the artifact available for inspection. This is where checks that need the actual contents run, such as malware verdicts and install-script detection.

An artifact request first runs the versions rules against the requested version, then the download rules. Either set can block the fetch, and every log entry an artifact request writes is a download entry.

Because every artifact fetch passes through it, the phase catches matching versions anywhere: direct dependencies, transitive dependencies deep in the tree, and installs driven straight from a lockfile that skip version resolution entirely. A block fails the request with an error naming the package, the version, and a request ID that looks up the log entry.

A failed build is the intended outcome in this phase. It is the right tool when no version substitution makes the problem acceptable: a malware verdict, a vulnerability threshold, a package that must never be fetched externally.

The upload phase

upload rules evaluate publishes before they reach the publish target. This is the only phase that sees what leaves the organization rather than what enters it, which is why secrets scanning runs here.

Using the phases together

The phases are separate gates: a version that survives versions filtering is still evaluated against the download rules. A common baseline uses both deliberately, for example a maxAgeHours window in versions to delay fresh releases without breaking installs, plus malware and vulnerabilities rules in download as hard stops. Soft policy where an older version is an acceptable answer, hard policy where no version is.

The policyPhase
An allowed version exists, steer clients to it (age windows, deprecated packages)versions
No matching version may enter, regardless of what breaks (malware, vulnerabilities)download
Control what gets published (secrets)upload

One operational difference: webhook events come from download and upload decisions. Metadata filtering never produces events, however many versions it removes. A versions rule that blocks an artifact request is a download decision, so that block does produce one.

On this page