
# Download verification

jup verifies a package manager before adding it to the cache. It also checks a project-pinned digest again when loading an existing cache entry.

## Verification methods

jup uses the best integrity information available for a request.

### Project-pinned digest

A digest may come from:

- the suffix in `packageManager`;
- `devEngines.packageManager.integrity`; or
- a resolution in `.corepack.lock`.

The digest must match the downloaded file exactly. A committed digest gives every jup installation the same expected bytes.

### Registry signature

For npm registry packages, jup can verify signed metadata with a trusted public key. A successful check means the metadata was signed by a key jup trusts and was not changed afterward.

### Registry digest

Some registry mirrors remove signatures. jup can instead compare the download with the digest in registry metadata. This checks file integrity but relies on the registry to supply the expected value. jup prints a warning when it uses this method.

Set `JUP_REQUIRE_SIGNATURES=1` when unsigned registry metadata must be rejected rather than checked through its digest.

## Unverified downloads

If none of these checks is available, jup refuses the download. `JUP_ALLOW_UNVERIFIED=1` bypasses that refusal and should not be a permanent setting.

If an artifact must be bootstrapped this way, scope the setting to one command:

```sh
JUP_ALLOW_UNVERIFIED=1 jup use yarn@4
```

Review where the artifact came from, then commit the digest written by `jup use`. Later runs can verify that digest without the override.

## Yarn Berry

Direct Yarn Berry downloads from `repo.yarnpkg.com` do not provide the signature or digest jup requires. You can:

1. configure an npm-compatible registry with `JUP_NPM_REGISTRY`, allowing jup to obtain Yarn from the signed `@yarnpkg/cli-dist` package;
2. bootstrap an exact digest once with `JUP_ALLOW_UNVERIFIED=1 jup use yarn@4`; or
3. for a range pin, create and commit `.corepack.lock` after the same one-command bootstrap.

Once the digest is committed, jup verifies it on every machine.

## Signing keys

jup includes npm's signing keys. If metadata refers to an unknown key ID, jup can retrieve npm's current official key list and cache the matching key under `JUP_HOME`. A cached key remains available offline.

Set `JUP_INTEGRITY_KEYS` to provide a fixed trust store. This value must come from the process environment; jup ignores it in `.corepack.env`.

`JUP_INTEGRITY_KEYS=0` disables registry signature verification. It does not disable comparison with a digest pinned by the project. Treat it as a security policy change, not as a routine response to a failed download.

Expired signing keys are rejected.

## Repository trust boundaries

Configuration stored in a repository has less authority than configuration supplied by the user or CI environment:

- `.corepack.env` cannot supply credentials, signing keys, certificate files, unverified-download flags, TLS verification controls, or unsafe custom URLs.
- A project `.npmrc` may choose a registry but cannot supply credentials or certificate authorities.
- Credentials are limited to their configured registry origin or `.npmrc` host and path.
- Tarball URLs and extracted archive paths are validated before installation.

These restrictions prevent a checked-out project from silently changing what jup trusts.

## If verification fails

Do not replace a digest or disable verification before checking the registry origin, mirror configuration, manifest, and `.corepack.lock`.

- For an unknown key, allow jup to refresh npm's keys or update jup.
- For an expired key, update the source or obtain an exact digest through a trusted process.
- For missing signatures, use a registry that supplies them or rely on the registry digest if your policy permits it.
- For a digest mismatch, independently verify why the bytes changed before updating the pin.

See [Troubleshooting](./troubleshooting#download-verification-fails) for a symptom-by-symptom checklist.
