BytesafeDependency Firewall

Selector functions

Reference for the named selector functions, vulnerabilities, malware, install-scripts, deprecated, unlisted, secrets, license, trust-downgrade, with their phases, ecosystems, and options.

A selector function is the computed condition in a rule's selector: instead of matching what a package is (name, version, upstream), it matches what is known about it. This page is the exhaustive reference; for how selectors fit into evaluation, see Rule evaluation.

A selector has at most one function, combined with the plain fields by AND:

{
  "function": {
    "name": "vulnerabilities",
    "options": { "maxCvssScore": 9.0, "maxEpssScore": 0.5 }
  }
}

Matrix

FunctionPhasesEcosystemsOptionsIn dashboard
vulnerabilitiesdownloadall except CondamaxCvssScore, maxEpssScoreyes
malwaredownload, uploadallminimumConfidence, effortyes
install-scriptsdownload, uploadnpm, PyPInoneyes
deprecatedversions, downloadnpm, PyPI, NuGetnoneyes
unlistedversions, downloadNuGetnoneyes
secretsuploadallignoredFiles, excludeTestFilesyes
licensedownloadall; Conda supports unknown onlylicenseSet, mode, unknownyes
trust-downgradeversionsnpmnoneyes

A dashboard label is presentation text for the API/config value. For example, Filter versions maps to versions, Install scripts to install-scripts, and Trust downgrade to trust-downgrade.

A function outside its phases simply never matches; malware, install-script inspection, and secrets scanning need the artifact, so they cannot act on version metadata.

Saving a rule or exception whose function does not support the firewall's ecosystem fails with 400. The same validation applies to full config imports and rollbacks.

Functions differ in what they cost to evaluate, and rules run cheapest first, so a rule carrying an expensive function is reached only when every cheaper rule has allowed the request. See Evaluation order and treat the exact order as an implementation detail.

vulnerabilities

Matches when the package version has a known vulnerability exceeding both thresholds: CVSS score strictly above maxCvssScore (0 to 10) and EPSS probability strictly above maxEpssScore (0 to 1). The dashboard defaults are maxCvssScore: 5, maxEpssScore: 0.

Not supported for Conda firewalls in the beta: the dashboard does not offer the function there, and the API rejects a JSON-configured rule or exception.

The log entry's rule output records the vulnerability IDs and the worst CVSS and EPSS values that triggered the match.

{
  "name": "vulnerabilities",
  "options": { "maxCvssScore": 9.0, "maxEpssScore": 0.5 }
}

See Block vulnerable packages. Where the data comes from and how scores are derived when data is missing: Advisory sources.

malware

Matches when a malware finding meets the rule's minimum confidence. Runs on the artifact itself, so it applies to downloads and uploads only.

minimumConfidence accepts known_malware (default), suspicious, or weak_indicator. It names the weakest finding that matches, so suspicious also matches known_malware, and weak_indicator matches all three levels. Any other value is rejected.

effort accepts known (default) or deep. Under known the rule decides on findings that already exist for the artifact: threat-intelligence datasets, plus any content analysis that has already been done. Under deep the artifact's contents are analyzed as part of the request and the rule waits for that result, which is more thorough and slower, and slowest on the first request for an artifact nobody has analyzed yet. Any other value is rejected.

Both options are independent. Effort decides how much is known when the rule runs, confidence decides how weak a finding may be and still match.

Omitting options is valid and means known_malware at known effort.

A matching log entry's output contains the finding summary in malware, plus scanner, confidence, and signals.

{
  "name": "malware",
  "options": { "minimumConfidence": "known_malware", "effort": "known" }
}

See Block malware.

install-scripts

Matches packages declaring code hooks that run on install or build. npm: any of preinstall, install, postinstall in the package's package.json scripts. PyPI: source distributions (.tar.gz, .zip) with a root setup.py or a root pyproject.toml declaring [build-system] backend-path (an in-tree PEP 517 build backend); wheels never match, and external build backends without backend-path do not match. Runs on the artifact, so downloads and uploads only.

The log entry's message names the detected hooks. The rule output carries a scripts array (npm) or a findings array with kind, path, and for pyproject findings backend and backendPath (PyPI). Results are cached per artifact SHA-256.

{
  "name": "install-scripts"
}

See Block install scripts.

deprecated

Matches versions their publisher has marked as discouraged: npm deprecation messages, PyPI yanked releases (PEP 592), NuGet deprecations.

{
  "name": "deprecated"
}

unlisted

NuGet only. Matches versions hidden from search results (listed: false in the catalog entry). On nuget.org, unlisted versions remain installable by anyone who knows the version; a rule with this selector blocks them.

{
  "name": "unlisted"
}

secrets

Matches when scanning the published artifact's contents finds at least one potential leaked credential. Runs on the upload phase only, so it acts on publishes, not installs. Detection covers several hundred credential formats, including Bytesafe's own access token formats.

Both options manage false positives:

OptionMeaning
ignoredFilesFindings whose path within the package matches one of these patterns are ignored. Exact path or a single leading/trailing * wildcard, as for packageName, but always matched case-sensitively
excludeTestFilestrue: ignore findings in test-looking paths (segments test, tests, __tests__, spec, specs, testdata, fixtures; file names ending _test, .test, .spec before the extension). Default false

The log entry's rule output lists the findings (rule, file, line, fingerprint) with the secret value redacted, capped at 20 entries with findingsTotal and truncated carrying the full count.

{
  "name": "secrets",
  "options": { "ignoredFiles": ["package/docs/*"], "excludeTestFiles": true }
}

See Scan for secrets on publish.

license

Matches a version by its resolved licenses (from a public license data source, falling back to the license declared in npm or NuGet package metadata) against a license set, or matches versions with no resolvable license at all. Runs on downloads only. Conda has no license data source in the beta, so Conda versions resolve as unknown license and only the unknown option has an effect there.

Exactly one of licenseSet and unknown must be set:

OptionMeaning
licenseSetID of the license set to match against
modedeny (default): match when any resolved license is in the set. allow: match when licenses resolved but none is in the set
unknowntrue: match when no license information could be resolved. No licenseSet allowed

License expressions are flattened to their mentioned IDs (no OR/AND evaluation, WITH exceptions dropped); matching is case-insensitive. Rules referencing a nonexistent set are rejected on save, and a set referenced by a rule cannot be deleted.

The log entry's rule output records the resolved licenses, the licenseSet, and the data source.

{
  "name": "license",
  "options": { "licenseSet": "<license-set-id>", "mode": "deny" }
}

See Enforce license policy.

trust-downgrade

npm only. Matches a version whose supply chain trust evidence (trusted publisher, provenance) is weaker than an earlier published version's, the pattern of an account-takeover release. Mirrors pnpm's trustPolicy=no-downgrade. In the dashboard, it appears in the rule form's function list on an npm firewall with the versions phase selected. Optionless.

The function needs the package's other versions to compare against. That set is available on npm metadata requests and on npm artifact requests, so a versions-phase rule using it also blocks a direct fetch of a downgraded version.

{
  "name": "trust-downgrade"
}

Unknown names

Config with a function name outside this list is rejected on parse (unknown selector function), so a typo fails the import instead of silently never matching.

On this page