BytesafeDependency Firewall

Block deprecated packages

Keep versions out of your builds that their own publishers have deprecated, yanked, or unlisted.

When a publisher deprecates a version, they are telling you not to use it: it is broken, superseded, or unsafe. Package managers surface this as a warning at best, and automation ignores warnings. Two selector functions turn the publisher's signal into policy: deprecated and, for NuGet, unlisted.

What counts as deprecated differs per ecosystem, and the selector maps to each registry's native signal:

EcosystemSignal matched by deprecated
npmVersion has a deprecation message
PyPIRelease is yanked (PEP 592)
NuGetVersion has a deprecation entry

Maven, Go, and Conda have no registry-level deprecation signal the firewall can read, so the selector is not available for those ecosystems. The full matrix is in the selector functions reference.

Add the rule

In the dashboard, open the firewall, go to Rules, and create a rule:

  • Execution phase: filter versions (called versions in config, API, and CLI)
  • Selector function: Deprecated (no options)
  • Effect: block and log

As JSON:

{
  "id": "block-deprecated",
  "executionPhase": "versions",
  "selector": { "function": { "name": "deprecated" } },
  "ruleEffect": { "block": true, "log": true },
  "description": "Filter versions deprecated by their publisher"
}

To apply the JSON without the dashboard: export the config with bsfw config export, add the rule to the rules array, and import it back. See config import.

On the versions phase the rule filters deprecated versions out of the metadata, so version ranges quietly resolve to a non-deprecated version. Add the same selector on download if you also want a hard stop for exact pins and lockfile URLs.

NuGet: also block unlisted versions

Unlisting is NuGet's soft removal: the version disappears from search but stays installable for anyone who pins it. Publishers unlist versions they no longer want consumed, including botched releases. A second rule closes that path:

{
  "id": "block-unlisted",
  "executionPhase": "versions",
  "selector": { "function": { "name": "unlisted" } },
  "ruleEffect": { "block": true, "log": true },
  "description": "Filter versions unlisted from search"
}

Roll out

Deprecated versions are common in older dependency trees, so unlike a malware rule, this one benefits from a dry run: deploy with { "block": false, "log": true } first, watch the log for what would be blocked, and fix or except the legitimate stragglers before enabling block. The pattern is described in Block vulnerable packages.

What developers see

Ranges resolve past deprecated versions without anyone noticing; that is the point. An exact pin to a deprecated version fails as not found on the versions phase, or with the blocked-download error if you added the download rule. See your ecosystem page for the exact client behavior.

When a deprecated version is still needed

A pinned build that cannot move yet: add an exception scoped to that package and version with reason no_upgrade_path and an expiry, rather than weakening the rule.

On this page