# Integrity Snapdir is built so that you never have to *trust* a store — you can *check* it. Because every object and manifest is [content-addressed](content-addressing.md), its address is also a cryptographic proof of its contents. Verification is just re-hashing the bytes and comparing the digest to the address you expected. This runs automatically on every fetch and on demand via the verify commands. ## The integrity guarantee The default checksum function is BLAKE3. When snapdir hands you bytes for an address `h`, it re-computes the BLAKE3 hash of those bytes and asserts it equals `h`. Because BLAKE3 is a cryptographic hash, a match means the bytes are — to cryptographic certainty — exactly what was stored: no silent disk corruption, no truncated download, no tampering in transit or at rest. This extends to whole trees. A directory's checksum is the [merkle](manifests.md#directory-checksums-the-merkle-rule) hash of its children's checksums, and the [snapshot ID](manifests.md#the-snapshot-id) is the BLAKE3 hash of the entire manifest text. So verifying a manifest against its snapshot ID, and each object against its checksum, verifies the *complete* snapshot end to end — one corrupted byte anywhere changes some checksum, which changes its line, which changes the snapshot ID. ## Verification on fetch Integrity is not an optional afterthought; it is part of the transfer protocol. When snapdir [fetches](../reference/snapdir-fetch.md) an object it: 1. downloads to a temporary path, 2. computes the BLAKE3 checksum of what arrived, 3. compares it to the requested address, 4. **retries on mismatch** (a corrupt or partial download is discarded), and 5. only then **atomically renames** the verified bytes into their sharded location. A failed checksum therefore never becomes visible at its address. This is what makes fetches safe to retry and resume. ## Verifying on demand You can also verify proactively rather than waiting for a fetch: - [`snapdir verify`](../reference/snapdir-verify.md) checks a snapshot's manifest and objects against their checksums. - [`snapdir verify-cache`](../reference/snapdir-verify-cache.md) re-hashes the contents of the local [cache](stores-and-cache.md) to detect on-disk corruption. ## Checksum modes and what they are for The checksum function used for the per-entry `CHECKSUM` field is configurable, but always produces a lowercase hex digest: | Mode | Purpose | | ------------------------------------------ | -------------------------------------------------- | | **BLAKE3** (default) | The security primitive and the basis of all guarantees. | | `--checksum md5` | Legacy/external interop only. | | `--checksum sha256` | Legacy/external interop only. | | Keyed BLAKE3 (`SNAPDIR_MANIFEST_CONTEXT`) | Domain-separated hashing via a context string. | A few rules: - **`md5` is not a security primitive.** It is offered purely for interoperating with external tooling that already speaks md5; it must not be relied on to detect tampering, since md5 collisions are cheap to construct. `sha256` is likewise primarily an interop choice. For any trust boundary, stay on BLAKE3. - **Keyed mode** derives the hash from a context string, set via the `SNAPDIR_MANIFEST_CONTEXT` environment variable. Manifests produced under different contexts are intentionally non-interchangeable. - The merkle rule and snapshot-ID derivation are **hash-agnostic** — they run unchanged under any mode — but [`snapdir id`](../reference/snapdir-id.md) always uses default BLAKE3 regardless of the `--checksum` selection. ## Where to go next - [Content addressing](content-addressing.md) — why an address is a proof. - [Manifests](manifests.md) — how checksums compose into a snapshot ID. - [Stores and cache](stores-and-cache.md) — the push/fetch discipline around verification. - Commands: [`snapdir verify`](../reference/snapdir-verify.md), [`snapdir verify-cache`](../reference/snapdir-verify-cache.md).