Installation verification across package managers#
Package hashes and Sigstore attestations answer different questions. A hash checks that downloaded bytes match a previously selected digest. A Sigstore attestation checks that an authenticated identity signed a statement about those bytes. Neither check alone establishes that the identity was authorized to publish a package.
Client behavior observed on 2026-08-11#
This comparison reflects the linked public documentation on 2026-08-11. Pinned source links identify the exact Pixi and uv revisions reviewed.
Client |
Artifact check during installation |
Sigstore attestation check during installation |
|---|---|---|
pip |
Checks an index-advertised download hash for corruption. |
None. PyPI documents a separate |
uv |
Records selected index hashes in |
None. |
npm |
Uses |
None. |
Pixi |
Verifies conda and PyPI package checksums recorded in |
None. Pixi creates or uploads Sigstore attestations for Prefix.dev publishing and documents external consumer verification with |
conda with conda-sigstore |
Conda retains its package digest checks. |
An opt-in direct package verifier requires valid CEP 27 evidence from a repodata-hash-pinned immutable sidecar or the separate deterministic Prefix.dev adjacent sidecar. PR 142 selection also needs conda to preserve |
The relevant primary documentation is:
PyPI is the repository in this comparison, not pip. PyPI validates supported attestations at upload, associates publish attestations with Trusted Publisher identities, and exposes provenance through its Integrity API. That gives a consumer enough repository context to perform an authorization check. pip does not consume that evidence during an ordinary install.
uv’s attestation support is also on the producer side. Its publisher passes adjacent PEP 740 JSON objects to a supporting index. Its current upload implementation notes that it does not validate the interior attestation structure beyond JSON before upload. This is transport behavior, not consumer verification.
npm also separates installation from signature and provenance verification.
npm audit signatures runs after npm install or npm ci, checks registry
signatures and available provenance attestations, and reports an error when a
registry that advertises signing keys omits or provides an invalid signature.
It verifies provenance when present rather than requiring every package to
carry it. It does not expose a consumer-managed identity policy or a reusable
verification receipt.
Pixi checks locked artifact digests during installation. Its Sigstore path is
separate and producer-oriented. pixi publish --generate-attestation and
pixi upload prefix --generate-attestation create and upload evidence for
Prefix.dev. The Pixi security guide directs consumers to external Sigstore
tools instead of claiming that pixi install verifies those attestations.
The closest existing consumer pattern is PyPI’s separate
pypi-attestations verify pypi --repository ... command. The repository is an
independent trust input. conda sigstore verify offers the corresponding
low-level choice through paired --cert-identity and
--cert-oidc-issuer options. They apply to one command and do not create
channel policy.
Why enforcement has one switch#
The plugin keeps installation enforcement either disabled or fail-closed.
conda sigstore audit is the nonblocking way to measure evidence coverage
before enabling enforcement. An ignore mode would duplicate the disabled
state, while a warn mode inside installation would duplicate the audit
workflow and make invalid evidence easy to overlook.
A client-maintained policy language would not establish who a channel
authorized to publish. That information needs to come from a standardized
channel delegation, like PyPI’s Trusted Publisher relationship, rather than a
new .condarc identity allowlist.
Verification reports are output, not reusable trust decisions. Trust material, transparency evidence, and verifier behavior can change between commands. This matches pip’s treatment of its installation report, which is not accepted as install input. The plugin therefore verifies evidence fresh instead of caching receipts.
Why verification runs before extraction#
An audit can measure evidence coverage after installation, but it cannot prove that invalid evidence was rejected before package files reached a prefix. The package-verifier hook makes an opt-in decision before extraction while conda still has the selected URL, expected digest, and archive.
The verifier uses the same evidence-validation pipeline as the explicit command instead of caching a receipt or reimplementing Sigstore inside conda. Exact transport behavior belongs in Commands, and the setting and recovery controls belong in Configuration and Configure verification.
Upstream status#
conda/conda#16518 provides the
pre-extraction verifier hook. This repository’s locked developer environments
build a pinned revision from jezdez/conda’s feature/package-verifiers
branch as a conda package. No released conda version provides that API yet.
The current conda PackageRecord model and solver conversion paths do not
preserve PR 142’s attestations_sha256 field. A separate conda change is
required before real solver and install flows can select
<artifact>.sigs.<attestations_sha256>. The adjacent Prefix.dev .v0.sigs
compatibility path needs only the selected package URL and digest. A rejection
prevents that archive from being extracted and linked, although concurrent
cache work for other packages may already have completed.
The exact upstream contract is listed in Upstream integration contracts.
For concrete conda-lockfiles and conda-workspaces commands, see
Verify locked environments during installation.