/ concepts / Trust model

This page is the “where does trust come from, and where does it stop?” companion to How it works. The mechanics on that page describe what the system does; this page describes what you have to believe for those mechanics to be meaningful.

Who you trust, in short #

OpenVet’s trust model is deliberately small: you trust the cryptographic primitives (signatures and content hashes), and you trust the logs you have chosen to subscribe to. That is it. Not the server hosting any log. Not the registry. Not the OpenVet project itself. Not other consumers. Just the math, plus the entities whose logs you have explicitly added to your openvet.toml.

Trust is purely consumer-side. There is no global “trusted auditor” list, no transitive trust graph, no built-in reputation system. What counts as trust is whatever each consumer puts in their own configuration.

Trust logs, not authors #

When openvet check evaluates a dependency, it considers every audit it finds in the logs you have subscribed to. It verifies that each audit’s signature is cryptographically valid, but it does not use signer identity to decide trust. There is no implicit “I trust Alice, so I trust everything she signs anywhere” — trust attaches to the log, not to the signer.

This is a deliberate choice. Transitive trust models (where trust in A implies trust in everyone A vouches for, and so on through a graph) are powerful but hard to reason about; a small mistake in delegation can cascade into trust you didn’t intend. OpenVet’s model is the opposite: your trust set is exactly the list of log URLs in your openvet.toml, nothing implicit, nothing transitive.

Two consequences:

  • You customise trust by picking which logs to subscribe to. Trust the audits in Alice’s log? Subscribe. Don’t trust them? Don’t subscribe. There is no middle ground at the protocol level, and the simplicity is the point.
  • For fine-grained control, republish into your own log. If you want only specific audits from another log — a curated subset for your team, say — the pattern is to import those audits into a log you own and have your project subscribe only to your log. Your log becomes the integration point you fully control.

What the math gives you #

The cryptographic primitives are what make “you don’t have to trust the server” actually true. Three layers, each defending a different attack:

  • Signatures. Every audit is signed by its author or authors; every commit in a log is signed by an authorised key from the log’s keyset. A tampered audit fails signature verification. A commit forged by a third party fails too. The server does not hold keys it doesn’t need, and it cannot produce signatures it isn’t authorised to produce.
  • Content addressing. Every audit, every commit, and every tree node is referenced by its content hash. Tampering with any byte changes the hash, and downstream references stop matching. This is what makes mirroring safe: a mirror is just another server handing out the same content-addressed bytes.
  • Append-only verification. When openvet update fetches a new log head, it verifies that the new head is a descendant of the head you previously pinned. A log that has been silently rewritten — by a coerced server, for instance — fails this check and the update aborts. The pin in openvet.lock is your anchor.

Together, these reduce the server to a byte-server. It can be slow, unavailable, or selective about what it serves. It cannot fabricate trust.

Custodial vs self-custody #

A zero-trust protocol that requires every user to generate and manage their own signing keys before they can publish anything is a protocol that very few people will use. To make the on-ramp tractable, the registry (openvet.org) supports two key-custody postures:

  • Custodial. When you sign up, the registry generates a signing key on your behalf and uses it to sign your audits when you publish from the browser. You can write and publish your first audit in under a minute, never having touched a key directly.
  • Self-custody. You generate your own key, enrol it in your keyset (via the openvet login flow or directly via the CLI), and optionally revoke the registry’s custodial key. From then on, the registry holds nothing on your behalf.

In custodial mode, you are trusting the registry not to misuse the key it holds for you — the same shape of trust you place in any account on any service. In self-custody mode, the trust collapses to “you and the cryptographic primitives.” The protocol supports both equally; the choice is yours.

The honest part: the choice is publicly visible. A log’s keyset is part of the log itself, and consumers fetch it whether or not they trust its host. Anyone subscribed to your log can see whether you are in custodial or self-custody posture and decide for themselves whether to trust audits signed under a custodial key. A consumer who wants the strictest trust model can subscribe only to self-custody logs.

This is how OpenVet unifies “easy on-ramp” with “zero-trust”: not by pretending the tradeoff doesn’t exist, but by making it inspectable.

When things go wrong #

Recovery is a first-class concern. The keyset model is designed so that routine key management happens within a log’s normal append flow, with no consumer-visible disruption.

  • Key compromise. Every key in a keyset carries a set of capabilities: auditor (sign audits), publisher (publish them to the log), and operator (modify the keyset). Configuring keys with restricted capabilities — a day-to-day key that can only sign and publish audits but not touch the keyset, say — limits the damage if it is compromised. The operator key (typically kept on a hardware token or in cold storage) signs an UpdateKey that revokes the compromised key, and any audits added by the compromised key can be removed or superseded by subsequent commits. To a consumer, the log just keeps moving forward.

  • Total operator-key loss. If every key with operator authority is lost or compromised, no key in the log can extend it further. The escape hatch is a generation bump: the server administrator, after out-of-band identity verification, starts a new generation under a fresh key. The previous generation’s audit history is preserved. Consumers see a warning on their next update and must explicitly edit a setting in their openvet.toml to accept the new generation — the manual step is intentional, because accepting a new generation is a trust-establishment decision, not a routine update.

The shared shape: revocation is forward-only, history is preserved, and recovery happens in-band wherever possible. The capability model also makes routine key rotation easy — add a new key with InsertKey, optionally revoke the old one with UpdateKey, all within the same normal append flow. The break-glass path (generation bump) is for last resort.

What OpenVet doesn’t defend against #

Some attacks are out of scope for cryptographic enforcement, and saying so up front is the honest part of a trust model.

Audit quality. A signature does not verify truth. A trusted auditor who marks safe-to-deploy carelessly is indistinguishable, at the protocol level, from one who marks it after exhaustive review. Curation of whose audits you subscribe to matters as much as the cryptographic checks.

Lazy or careless auditors. OpenVet surfaces signed assertions; it does not assess the rigour behind them. A culture and a reputation system for audit quality has to develop around the protocol; the protocol does not enforce one. Out-of-band key compromise without revocation. If an auditor’s key is compromised but the auditor never publishes a revocation, audits forged with the stolen key continue to verify cryptographically. The system depends on prompt revocation when keys are known to be compromised.

Server withholding, and split-view in custodial mode. A server can always decline to serve new commits to a targeted consumer, leaving them stalled at an older head — they may miss a recent revocation or audit. In self-custody mode, this is the worst the server can do; with no signing key it cannot forge a divergent history. In custodial mode, however, the registry holds the signing key on the user’s behalf and could in principle use it to sign a forged divergent history for a targeted consumer (a true split-view). Content addressing makes divergence detectable to anyone who fetches the log from more than one host and compares — but a consumer fetching from a single host will not detect it.

Broken cryptographic primitives. If the signature scheme, hash function, or tree construction is broken, the trust assumptions break with them. The wire format reserves namespaces so future migrations to new primitives can be done without signature confusion.

Further reading #

The mechanics underlying the trust shape described here live in How it works. The wire-level details of the keyset, the capability model, the proof-of-possession scheme, and the recovery flows live in the specification.