Skip to content
GitHub

Supply-chain security

Understand Depsilo v0.9.4 malicious-package blocking, artifact tamper detection, and safety-disabled minimum-release-age enforcement.

Depsilo places policy between package managers and upstream registries. v0.9.4 provides three independent controls:

Control New-install default Result Primary boundary
Minimum release age Unavailable Positive thresholds in an enabled configuration are rejected at startup Waiting for end-to-end artifact-source and timestamp provenance
Known-malicious blocklist On, sync every 6 hours Refuses matched versions with HTTP 451 MALICIOUS_BLOCKED Covers only OSV MAL-* records with confirmed identities
Tamper detection On Retains a first-seen hash and raises a critical alert; no 451 Passive trust-on-first-use, not authentication of the initial fetch

These controls are independent. The unavailable minimum-release-age gate does not disable the malicious-package blocklist or tamper detection.

Interpret threshold settings from older releases only with that release’s notes. In the current release, use reviewed Package Rules or the known-malicious blocklist for explicit security decisions. This unavailable gate does not change cache, upstream, or other policy behavior.

The malicious-package blocklist is enabled by default:

[supply_chain.blocklist]
enabled = true
sync_interval = "6h"
# mirror_url = "https://osv-vulnerabilities.storage.googleapis.com"
# proxy = "http://127.0.0.1:7890"

v0.9.4 synchronizes MAL-* records from the OSV malicious-packages dataset for npm, Cargo, Composer, NuGet, Go, and Maven. It imports explicit affected-version lists and all-version advisories. Bounded ranges without an explicit version list are skipped because this release does not infer those ranges.

Matching happens before release-age and allow-list checks. A matching artifact already in cache is no longer reachable through this gate, although its bytes remain in storage until LRU or operator cleanup. For a confirmed false positive, an administrator can create an audited override lasting at most 24 hours. It cannot be extended in place; continued access requires another recorded decision.

Synchronization fails open in a bounded way:

  • Existing local data remains active after a failed refresh.
  • An empty local dataset blocks nothing.
  • A synchronization error does not stop the entire proxy from serving packages.
[supply_chain.tamper_detection]
enabled = true

For artifacts treated as immutable, Depsilo records SHA-256 during the first streaming fetch. If a natural background refresh later returns different bytes for the same version, Depsilo refuses to replace the cached content, keeps the first-seen cached copy, and writes a critical tamper_detected event. It can also notify a configured webhook. If LRU has already evicted the first-seen copy, a later cache miss stores and serves the re-fetched bytes before comparing them with the retained hash baseline. Depsilo alerts, but the old copy can no longer be restored.

The limitations are as important as the alert:

  • Detection is passive. It compares bytes only during a normal background refresh or a re-fetch after eviction, and does not actively probe upstream.
  • It is an alerting mechanism, not a generic blocking policy, and does not return 451.
  • “First seen” is a local baseline, not a signature or transparency-log proof. If the first fetch is already compromised, its hash becomes the baseline.
  • After LRU evicts the original cached bytes, inconsistent new bytes are already stored and may be served before verification. Depsilo can still alert using the old hash, but it cannot restore the old artifact.

Common bypass paths include:

  • A direct additional pip index. Do not point --extra-index-url at an uncontrolled upstream.
  • A Go GOPROXY fallback such as |direct that connects directly after an error.
  • Composer may fall back to the original dist URL when a mirrored dist is refused. Hard blocking requires restricting client access to those original download hosts.

Depsilo can preserve ecosystem checksums or signatures, but it cannot turn an unsigned artifact into one with proven provenance. It does not replace upstream signing, build attestations, lockfiles, or SBOMs. Minimum-release-age enforcement is currently unavailable; the blocklist rejects known records; tamper detection reports same-version byte changes. None is a complete proof that a package is safe.

Quarantine blocks, allow bypasses, approvals and revocations, malicious package blocks and temporary overrides, and tamper events are recorded in the database. Admin can filter them by ecosystem, action, and package. With webhooks configured, quarantine and malicious-package blocks can notify immediately, while tamper mismatches use critical severity.

Before rollout, verify at least once that:

  1. A positive minimum-release-age threshold is rejected at startup.
  2. A reviewed Package Rule blocks a request and leaves an audit event.
  3. Blocklist synchronization status and the last successful refresh are visible.
  4. Clients have no fallback registry or direct network route around the proxy.
  5. Audit events and webhooks reach the intended operator channel.