/ announcements / OpenVet Registry: first preview deployment
registry preview

OpenVet Registry: first preview deployment

The OpenVet Registry is now live at openvet.org as a preview deployment. The registry is a public, collaborative host for cryptographically signed software dependency audits: a place for auditors to publish their work and for projects to subscribe to the auditors they trust.

OpenVet is a tool that tries to make it possible, affordable and scalable for projects to adopt audited-dependencies workflows. The status quo today is that most projects use dependencies without reviewing what they do. As a collective, we place implicit trust in packages published in registries. Large corporations can afford teams dedicated to reviewing dependencies, but most projects cannot. The OpenVet command-line tool tries to make it easy to audit packages, and to consume those audits. The registry tries to make it easy to publish those, and discover logs. If you want to know more, the docs have a longer answer.

WARNING

This is a preview deployment. The registry is operational and I’m dogfooding it daily, but the data structures behind it aren’t yet frozen. Expect that I’ll occasionally change something and reset the registry in the process. Don’t host audits here that you can’t afford to lose until I drop the preview label.

What you can do with it today #

I run openvet against the OpenVet repository as a continuous dogfooding exercise. The output below is real, from a check in mid-May 2026 — the numbers are what they are.

Setup #

openvet init drops a starter openvet.toml. Mine, after a few edits, looks like this:

[log.xfbs]
url = "https://openvet.org/xfbs"

[[lockfile]]
kind = "cargo"
path = "Cargo.lock"

[requirement]
benign = "is-benign"
crypto = "uses-crypto implies crypto-safe and crypto-tested"
unsafe = "uses-unsafe implies unsafe-safe and unsafe-tested"

I trust one log (my own, at openvet.org/xfbs), I want to gate the Cargo.lock, and I declare three requirements: every dependency must be benign, must be safe-and-tested if it uses cryptography, and must be safe-and-tested if it uses unsafe code. The requirement syntax is boolean over claim names — see claims vocabulary and requirement syntax in the docs for the full set.

Pin and verify the logs you trust #

openvet update fetches each audit log you’ve subscribed to in openvet.toml, verifies its signature chain end-to-end, and writes the new head into openvet.lock:

$ openvet update
xfbs: verified 50 new commit(s) (0 keyset / 0 gen-root); head 117574148ceb -> cb6e938a4ced
wrote openvet.lock

The signature verification is local — the registry’s only job here was to serve bytes. The pinned head in openvet.lock is what guarantees the same verdict on every machine running openvet check later.

Gate your project against the audits #

openvet check walks your lockfiles, evaluates each requirement against the audits in the logs you’ve pinned, and exits non-zero on anything that doesn’t satisfy your policy:

$ openvet check
✘ cargo:matchers@0.2.0
└─ unsafe: ✘ contradicted
   └─ from xfbs: ✘ false
      └─ any → false
         ├─ not → false
         │  └─ uses-unsafe → true
         └─ all → false
            ├─ unsafe-safe → true
            └─ unsafe-tested → false
Summary: 53 passed, 505 failed, 13 skipped

(output trimmed)

When a requirement fails, check prints the resolution tree: which auditor’s statement contradicted it, which claim atoms combined under three-valued logic, and which atom resolved to which value. The full mechanics live in How it works.

The 505 failed is honest — most crates in OpenVet’s own dependency tree don’t have audits in my log yet. That’s the work; closing the gap is the next stretch of dogfooding.

Ask concrete questions about your dependency tree #

openvet query <expression> walks your lockfiles and reports the state of a requirement expression across them. It uses the same parser and evaluator as [requirement] in openvet.toml — anything you can write as a requirement, you can pass to query. The simplest case is a single claim atom: which of my crates use unsafe code, according to my pinned audits?

$ openvet query uses-unsafe
warn  openvet@0.4.0 (path / workspace dep)
warn  openvet-audit@0.4.0 (path / workspace dep)

✓ cargo:bitflags@2.11.1
✓ cargo:log@0.4.29
✓ cargo:matchers@0.2.0
✓ cargo:once_cell@1.21.4
✓ cargo:tempfile@3.27.0
✓ cargo:tracing@0.1.44
✓ cargo:unsafe-libyaml@0.2.11
✓ cargo:zeroize@1.8.2

Summary: 30 match, 35 contradicted, 493 unknown, 13 skipped

(output trimmed)

match is the count of dependencies the expression resolves to true for. contradicted are dependencies where audits disagree under three-valued logic. unknown is the long tail where no pinned audit provides enough information to resolve the expression. Compound expressions work the same way — openvet query "uses-unsafe and impl-crypto" would count only dependencies where both atoms resolve to true. The summary line on its own tells you the coverage of a given property across your tree.

What’s in this deployment #

The registry implements the OpenVet protocol. It’s not a central trust anchor — the command-line tool will work with anything that speaks the protocol. You can host your own log on anything that can serve data over HTTP/HTTPS, and get the same functionality. The public deployment exists to make participation low-friction. Signup is two clicks if you have a GitHub account. It defaults to custodial keys, so you don’t have to manage your own keys (unless you want to, which is perfectly fine, and encouraged), all to make the process of adopting it as easy as possible. The registry is free, and it will always be. It’s not a SaaS, it’s just a (public) service.

What’s working today:

  • Account signup and custodial keys. New accounts get a registry-held signing key by default. Custodial keys are published in your keyset like any other, so consumers can verify audits you sign with them.
  • Publishing audits from the CLI. Author audits locally, sign with a self-held key, and push to your registry-hosted log. End-to-end without going through the UI.
  • Package search. The registry actively synchronizes package registry contents, so you can search for packages on openvet.org, and find matching audits. Currently, only synchronization with crates.io is enabled on the hosted registry, but more will be enabled soon.
  • Audit log hosting for any ecosystem. Audits can be hosted here regardless of which ecosystem the audited package comes from.
  • Raw log endpoints for subscribers. The CLI subscribes directly to a log’s HTTP endpoint and verifies the signature chain locally; the registry’s job is to serve bytes.

What’s still rough #

In the spirit of “should I use this yet?”, a candid list:

  • Data structures may still change. Some breaks will be migrations; some will be hard resets of the registry’s data. Until I drop the preview label, anything you publish here should be considered ephemeral.
  • The web UI is pre-pre-beta. The basic flows (login, searching packages, viewing audits) work. Some things may look strange, or be subtly broken.
  • Self-custodial setup doesn’t fully work yet. You can add your own key to your log’s keyset, but there is currently no way to remove the custodial key and give your own key operator privileges.
  • Search beyond cargo is dark. RubyGems and PyPI syncers are implemented but not yet enabled in production. npm and Go are next. The work is queue-and-storage, not a code rewrite.
  • No mirroring story yet. Self-hosting a log on static storage works, but tooling for “mirror this registry-hosted log to your own server” isn’t shipped.

Try it #

Browsing the registry is open, no account required. Visit openvet.org and search for a crate (try serde) to see what audits exist for it, or open my profile to see what one auditor has published.

To participate, sign in with GitHub (two clicks). The registry mints you a log slug and a custodial signing key. From there:

  • Click Trust on any profile to follow that auditor — their audits flow into your feed.
  • Under Settings → Keys, add your own key. The UI gives you a one-line openvet login command to run in your terminal, which pairs the CLI with your log. You can create, sign and publish audits from the CLI, and they will show up in the registry.

To gate your own project against the audits, the CLI section above walks the loop: install the CLI, declare a log to trust, run openvet update and openvet check. The Quickstart in the docs is the end-to-end version.

What’s next #

OpenVet is still under development. I am working on the specification, the command-line interface, and the backend in parallel. As new bits get released, I will make announcements on this blog, explaining what works, what doesn’t, what is stable, and what isn’t.

One of the outstanding pieces that will be released in the upcoming days is an initial version of the OpenVet specification, which still needs some cleaning up. The registry is the piece that is the most behind: audits already render fine, but there is no web-based auditing flow implemented yet. There are a lot of rough edges and unimplemented pieces. The command-line tool is in better shape, but is still missing some important features, such as signing with encrypted keys, or supporting signatures with anything besides sshsig.

Find it / report it #

If you’d rather reach me directly, my GitHub profile has the contact info.