4 releases (breaking)
Uses new Rust 2024
| new 0.5.0 | May 18, 2026 |
|---|---|
| 0.4.0 | May 13, 2026 |
| 0.3.0 | May 12, 2026 |
| 0.2.0 | May 6, 2026 |
#536 in Configuration
Used in 2 crates
290KB
5.5K
SLoC
openvet-policy
Requirement language and evaluator for OpenVet. Turns a project's TOML-defined policy and the audits collected for a single subject into a pass or fail verdict with structured per- requirement diagnostics.
The wire format and evaluator semantics are specified in detail in the policy specification. this README covers the high-level idea and the practical surface.
Requirements, claims, expressions
A claim is a (name, bool) pair emitted by an audit (e.g.,
uses-unsafe: true). OpenVet's canonical claim vocabulary —
defined in the vocabulary specification — is
deliberately atomic: each claim is an observable property of the
code (does the package contain memory-unsafe code? does it perform
network operations? was the unsafe code specifically reviewed?)
rather than a context-sensitive judgement like cargo-vet's
safe-to-deploy.
A requirement is a boolean expression over claim names that the
consumer wants to hold for every dependency — (not uses-unsafe) or unsafe-safe, for example. The evaluator runs each
requirement's expression against every audit's claims and then
collapses across audits into a single verdict.
Expressions support and, or, not, implies, and
parentheses with standard precedence (not binds tightest, then
and, then or, then implies). implies is right-associative
and desugars to (not a) or b, so impl-crypto implies crypto-impl-safe is exactly (not impl-crypto) or crypto-impl-safe. Claim names are [a-zA-Z_][a-zA-Z0-9_-]*.
TOML shape
# Bare form: default-on requirement, value is the expression.
[requirement]
safe-to-deploy = """
is-benign and
(not uses-unsafe or unsafe-safe) and
(not impl-crypto or crypto-impl-safe) and
(not uses-network or network-safe)
"""
# Table form: opt-in by overriding into the requirement set.
[requirement.fuzz-tested]
condition = "has-fuzz-tests"
default = false
# Per-subject overrides. Matcher fields are AND'd; "*" / omitted = wildcard.
[[override]]
registry = "cargo"
package = "libc"
requirements = { add = ["fuzz-tested"], remove = ["safe-to-deploy"] }
[[override]]
package = "serde"
requirements = ["safe-to-deploy"] # replace form
# Cross-log claim renames: "log:claim" → canonical name.
[alias]
unsafe-safe = ["mozilla:audited-unsafe", "google:unsafe-verified"]
Overrides and aliases
The effective requirement set for a subject is computed by walking
the [[override]] blocks in declaration order: each override whose
matcher matches the subject either replaces the working set or
patches it, depending on whether requirements is a plain list
(replace) or an { add = [...], remove = [...] } table (patch).
Aliases let a consumer treat differently-named claims from different logs as the same canonical claim. They apply at claim-lookup time — an audit from a log not listed under an alias falls through to the canonical name unchanged.
Evaluation
Three-valued Kleene logic per audit (True, False, Unknown)
with standard short-circuiting: False short-circuits and,
True short-circuits or, and not Unknown == Unknown. The
Unknown branch is load-bearing — an audit can perfectly well not
have an opinion on impl-crypto, and that is not the same as
actively asserting impl-crypto: false.
A requirement passes for a subject iff at least one audit returns
True and no audit returns False. Fail variants distinguish
nobody had enough info (NotAsserted) from an audit explicitly
disagrees (Contradicted); the latter carries a snapshot of the
relevant claims so the failure message can show why.
A subject passes iff all of its effective requirements pass.
Users
This crate is used by the openvet command-line tool.
Dependencies
~5.5–9MB
~193K SLoC