Skip to content

Policy overview

A registry policy turns the registry into a gate. Without a policy, every version a reader is entitled to is visible. With one, each version is either:

  • Promoted: passes every rule; visible and resolvable by consumers.
  • Held: fails at least one rule; stored and inspectable by owners, invisible to consumers.

Policy is evaluated deterministically on every read. Nothing needs to be re-run when conditions change: when a quarantine expires, an advisory is withdrawn, or an approval lands, the version promotes on the next read, instantly.

On publish registries, a few rules can additionally reject at publish instead of holding. Versions are immutable, so accepting a publish that can never pass burns its version number forever; when the failing fact is frozen into the tarball (vcs, license) or the remedy is a standing trust rather than a change to the version (new_publisher, vcs_downgrade, repository_change), rejecting keeps the number free: fix the problem and publish the same version again. Each of those rules has a reject toggle; see the rules reference. Mirrors never reject: there is no publish to refuse, so imported versions always hold at read time, and a mirror’s policy has no reject toggles.

  • The Held tab on the registry lists everything currently held, why, and what would release each version. It opens on the versions still needing review, and an owner can accept a hold to take it out of that queue without releasing it; see Reviewing a hold.
  • The crate page shows per-version status, hold reasons, remaining quarantine, and advisory badges — and lets owners manually block a version pending re-review.
  • The Policy tab shows the registry’s rules. Every reader of the registry can see the policy; only owners can edit it.

Each failing rule clears its own way:

  1. By time: quarantine expires on its own.
  2. By fixing the input: attach the missing SBOM, add attestations, or adjust the policy itself (for example, extend the license allowlist).
  3. By manual promotion: owners can waive most rule failures for one specific version. When the number of distinct owner identities approving reaches the registry’s threshold (2 by default), that rule failure is waived for that version. Partial approvals show their tally on the version until the threshold is met.
  4. By standing trust: a new_publisher hold clears for all of a publisher’s versions once enough owners vouch for the publisher; a vcs_downgrade hold clears for all of a crate’s provenance-less versions once enough owners trust its new state; a repository_change hold clears for all versions declaring the new repository once enough owners trust that URL. These are standing trusts in the person or the crate’s new state, not one-version waivers. Any single owner can revoke one, and revocation re-holds whatever only that trust was releasing.
  5. By resolving a manual block: a version an owner blocked clears when the blocking owner withdraws their own block, or when promotion approvals reach the threshold like any other waiver.

Advisory holds are the exception: they cannot be waived. No number of approvals promotes a version held by an advisory. Either the advisory is resolved upstream, or an owner allows that advisory’s id outright, from the Held tab or the policy’s ignored list, which stops it holding anything in the registry. This keeps “we out-voted the CVE” from ever being a thing. Version pins share the no-waiver rule: the pin itself is the standing decision, and editing or removing it is the only release.

Rules compose; a version must pass all of them. A reasonable starting point for a mirror: quarantine of a few days, advisory levels set to vulnerability and unsound, and publisher trust enabled. For a publish registry: an SPDX license allowlist and require_clean_vcs. The full catalog of rules, defaults, and failure semantics is in the Policy rules reference.

When the built-in rules stop being enough, registries can declare their own per-version facts (test coverage, unsafe counts, internal scanner verdicts), record them through the API from any pipeline, and write policy rules over them: see Custom facts & rules.