Verify the registry
Don’t trust us, verify us. privatecrates-verify is open source and runs in your own CI with a read-only
token. It checks everything PrivateCrates has written to your storage repository.
Run it every hour
Add this workflow to the storage repository itself:
name: verify registry
on:
schedule: [{ cron: "17 * * * *" }] # hourly
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with: { fetch-depth: 0 }
- uses: actions/cache@v4
with: { path: .privatecrates-verify.json, key: verify-${{ github.run_id }}, restore-keys: verify- }
- uses: cargo-bins/cargo-binstall@<commit sha> # pin to a commit
- run: cargo binstall --no-confirm privatecrates-verify
- run: privatecrates-verify --registry https://acme.privatecrates.dev
env: { GITHUB_TOKEN: "${{ github.token }}" }It needs the full git history (fetch-depth: 0) and uses the job’s own GITHUB_TOKEN with contents: read. The cache keeps a small state file of the
versions already verified, so each run checks only what is new.
What it reports
- Any change to the index history other than appends by our storage App and
yankedflips. - Any change by the storage App to an existing owners file or to
privatecrates.toml. The App only ever creates an owners file at a crate’s first publish; every other change there must come from a person. - Any version whose release is missing, is not immutable, or whose
.cratedigest differs from the index checksum. - Any version whose provenance is missing, has an invalid GitHub signature, names a different crate, version or checksum, or names a repository, workflow or environment the owners file did not allow at the time.
- Every manual publish, for review, on crates that allow them.
- Crate names that clash with crates.io.
Reading the results
A clean run prints one line and exits with status 0:
Verified: nothing to report.Otherwise it prints one line per finding, labelled ERROR, warning or info, and exits with status 1 if there is any error, which fails the workflow and notifies you
the way any failed workflow does. Status 2 means it could not run at all. Add --json for machine-readable
findings.
Run it promptly
GitHub rotates the keys that sign OIDC tokens, and old keys eventually disappear. Provenance has to be checked while the key is still published, which is why hourly is recommended. A version the verifier could not check in time is reported.
Options
| Option | Default | Purpose |
|---|---|---|
--registry | required | Your registry’s base URL. |
--repo | GITHUB_REPOSITORY | The storage repository, owner/name. |
--token | GITHUB_TOKEN | A token that can read the storage repository. |
--clone | . | The local clone, with full history. |
--state | .privatecrates-verify.json | Where to record what has been verified. |
--json | off | Print findings as JSON. |