4 releases (breaking)
Uses new Rust 2024
| new 0.4.0 | May 13, 2026 |
|---|---|
| 0.3.0 | May 12, 2026 |
| 0.2.0 | May 6, 2026 |
| 0.1.0 | May 1, 2026 |
#359 in Cryptography
4MB
25K
SLoC
openvet
The command-line interface for OpenVet. Write, sign, and publish audits to your own log, and gate your project against a policy expressed over the audits other people publish.
You can use this to initialize an openvet.toml configuration file in your
projects, where you define which audit logs you trust, and which requirements
to gate your project against.
The openvet check command will parse your lockfiles, fetch any matching audits
from the audit logs you trust, and either pass or fail with a message describing
the reason for the result (for example, that a dependency you use is not audited,
or that it is audited but it does not pass your requirements).
OpenVet is designed to be secure and fast to run. Any audit logs you trust are validated to ensure that their signatures are valid and that they have not been tampered with. Audit logs objects you've fetched are cached locally, to ensure that checking is fast.
The openvet update command will update the pinned audit log heads in your
openvet.lock file to the latest available head, validating new commits as you
go. This is the trustless design: you do not need to trust the audit log provider,
as you are validating the logs locally.
The command-line tool also allows you to audit code locally and publish it to your own log. There is a command-line driven workflow for doing this, and a TUI workflow for auditing code interactively.
Installation
The easiest way to install the command-line interface is via Cargo.
cargo install openvet
Usage
Consumer flow
Declare which logs to consult, then gate the project's lockfiles against a policy expressed over the audits in those logs.
openvet init # creates openvet.toml
$EDITOR openvet.toml # add [log.*], [[lockfile]], [requirement]
openvet update # fetch + verify log heads, write openvet.lock
openvet check # gate the project's lockfiles against the policy
openvet check --verbose # also print one line per passing subject
openvet log alice # walk a log (newest commit first)
A minimal openvet.toml:
[log.alice]
url = "https://openvet.example/alice"
[[lockfile]]
kind = "cargo"
path = "Cargo.lock"
[requirement]
safe-to-deploy = "safe-to-deploy and not unsafe-code"
[[override]]
package = "libc"
requirements = { add = ["sandbox"] }
See openvet-policy for the requirement language in
detail, and openvet-lockfile for the lockfile formats
accepted in the kind = "..." field.
Authoring flow
When creating audits, OpenVet has a concept of a workspace. This is
a directory that openvet audit new creates which contains the unpacked
package contents, the audit.pb file, a manifest.json file, and a VCS
checkout of the package (if the metadata is available).
You'll need a publish target and an SSH identity in your user config
at ~/.config/openvet/config.toml:
[publish]
log = "https://openvet.example/alice"
[identity]
key = "~/.ssh/id_ed25519"
The audit lifecycle:
openvet audit new cargo:serde@1.0.210 # fetch + unpack into ./audit-cargo-serde-.../
cd audit-cargo-serde-1.0.210-*
openvet audit edit # ratatui TUI: Summary / Files / Findings / Claims
openvet audit sign # sign audit.pb in place
openvet audit publish # extend your log
Or drive each subcommand from the shell instead of the TUI:
openvet audit claim safe-to-deploy true
openvet audit summary "Looked clean."
openvet audit findings add -m "Questionable transmute in src/de.rs:42" --claim safe-to-run
cd contents/src && openvet audit annotate lib.rs --lines 10-20 -m "unsafe block"
audit publish and audit publish --update are explicit about
intent: the first errors if the subject is already audited, the
second errors if it isn't. To retract an audit, openvet audit remove cargo:serde@1.0.210#sha256:....
Keyset management
Every log has a keyset, which defines the list of keys that may
alter the log's state.
Operators manage their log's keyset
through openvet keyset. Each entry carries a set of capabilities
(auditor, publisher, operator), an optional label, and the
proof-of-possession that established the key's ownership at
enrolment time.
openvet keyset list # walk the keyset
openvet keyset show "SHA256:..." # detail one entry
openvet keyset add ./new_key --cap auditor # enrol a new key
openvet keyset edit "SHA256:..." --cap +operator # incremental cap change
openvet keyset edit "SHA256:..." --revoke # drop all caps
Custodial onboarding
When a hosted OpenVet server creates a log on a user's behalf, it
issues a token URL that can be handed to openvet login. The CLI
signs a proof-of-possession with the local SSH key — the private
key never leaves the machine — and the server adds the pubkey to
the keyset.
openvet login https://openvet.example/alice/login/<token>
The reference openvet-server does not implement these endpoints
(it does not hold custodial keys); this flow is meant for hosted
server variants.
Package utilities
openvet package exposes the package crate's primitives outside
the audit flow — useful for scripting, inspection, and offline
cache priming.
openvet package resolve cargo:serde@1.0.210
openvet package download cargo:serde@1.0.210#sha256:...
openvet package extract serde-1.0.210.crate
openvet package manifest cargo:serde@1.0.210#sha256:...
Configuration and storage
Three places hold state:
openvet.toml(per project) — logs, lockfiles, and policy. Auto-discovered by walking up from cwd.~/.config/openvet/config.toml(per user) — publish target, identity key, cache preferences.openvet.lock(per project) — each log's verified head, written byopenvet update.
Reads go through a local sqlite cache at ~/.cache/openvet/cache.db.
Heads are intentionally never cached. [cache] compression_allowed = ["zstd"] (default) makes the CLI negotiate end-to-end zstd with the
server. There is no GC command yet.
Resolution chain for --key, --log, and similar flags: CLI flag →
OPENVET_KEY / OPENVET_LOG env var → user config → error with
hint.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Dependencies
~78MB
~1.5M SLoC