Skip to content

The trust model

doze up downloads and executes binaries. That sentence is why this page exists: a tool that fetches executables owes you a story about why you can trust what it runs — especially a dev tool, because dev machines hold source code, credentials, and production access.

Two supply chains meet on your machine, and every link is verified:

Modules (the plugins that provide each engine) come from a signed registry:

  1. The registry has one ed25519 keypair, and its public key is compiled into doze. doze does not fetch the key and does not learn it on first use, so a compromised registry host cannot hand a fresh install a key of its own. Rotating the key takes a doze release.
  2. Each module’s index is signed as a whole — not just its artifacts. The index carries the metadata that selects what you run: which releases exist, which engine versions each supports, which plugin protocol it speaks, where the channel points. Signing the index means a compromised CDN can’t claim false compatibility or roll the channel back to a vulnerable release.
  3. Each archive’s checksum is signed individually. The archive host (GitHub releases) is untrusted by design — tampered bytes fail verification no matter who serves them.

Engine binaries (the actual Postgres, Valkey, …) are fetched by the module from the doze-binaries mirror: built from upstream source in public CI, published append-only (a released version is never rebuilt), and checksum-pinned in your lock.

doze.lock — committed next to your config — pins three layers:

engines: # engine binaries: version = 16 -> 16.14.0 + per-platform SHA-256
modules: # per engine: module release, plugin protocol, supported
# engine versions, per-platform hashes

The consequences are the guarantees:

  • Reproducibility. A teammate’s clone and your CI resolve to byte-identical software — verified, not hoped.
  • No drift. A moving registry can’t change what a locked project runs. Warm caches resolve fully offline.
  • Explicit change. Pins move only via doze modules upgrade (and the updated lock goes through code review like anything else).
  • Immutability upstream. Published (version, platform) artifacts are never rebuilt — the tooling hard-errors on changed bytes — so a lock committed today resolves forever.

You declare the engine version (version = 18) — the software your app talks to. The module version (the plugin’s own release) is selected automatically: newest release compatible with your doze’s plugin protocol and every engine version you declared, then locked. You never write it; you meet it only in doze modules output and in error messages that name their own fix (run 'doze modules upgrade postgres').

This split is what makes evolution safe: a module can ship a new config argument or support a new Postgres major without touching what any locked project runs, and your project adopts it in one reviewed commit.

Honesty section: signatures prove who published, not that the code is benign — a malicious publisher signs malware happily. Every module in the registry is built in public CI from public source, and each module’s registry page shows its provenance, signature status, and exactly what config it accepts — generated from the module itself. The key is only as trustworthy as the doze binary that carries it: get doze from a source you trust.

For how the registry is built and operated, and for mirroring engine binaries, see how the registry works.