DevSafe / Docs
Docs CLI devsafe verify

devsafe verifyPaid

Proves your backup is restorable without trusting the storage provider. Zero-knowledge: DevSafe verifies the integrity of every git bundle in user-owned storage against a signed commitment, then tells you whether a full restore would succeed.

Usage

terminal
$ devsafe verify <repo-id>

The repo-id is the identifier shown by devsafe status. You can also pass a local path and DevSafe will resolve the repo ID automatically.

What it does

When you run devsafe verify, three things happen in order:

The result is a yes-or-no answer: can this backup be fully restored? No partial results, no "probably fine." Either every bundle passes all three checks, or verification fails.

Example output

terminal
$ devsafe verify api-server
→ fetching bundle inventory from R2...
→ found 47 bundles (sequence 001–047)
→ verifying chain integrity...
 Merkle chain intact (47/47 links)
→ verifying AEAD authentication tags...
 all 47 bundles pass authentication
→ verifying git bundle restorability...
 all 47 bundles pass git bundle verify

 api-server: VERIFIED
  bundles: 47
  total size: 284 MB (encrypted)
  chain root: a3f8c1...d902
  latest commit: e7b4f2...1a08 (main, 12 minutes ago)
  proof signature: sig_v1_9c4a...bf21

If verification fails, DevSafe tells you exactly which bundle broke and why:

terminal - failed verification
$ devsafe verify design-tokens
→ fetching bundle inventory from R2...
→ found 23 bundles (sequence 001–023)
→ verifying chain integrity...
✗ chain break at bundle 019
  expected hash: 7f2a91...c403
  actual hash:   b8d0e4...1f7a

✗ design-tokens: FAILED
  cause: bundle 019 was modified after encryption
  action: run "devsafe backup --force design-tokens" to create a fresh chain

Flags

--verbose
Print each bundle's hash and verification result as it is checked. Useful for large repositories with hundreds of bundles.
--json
Output the full verification result as JSON. Useful for CI pipelines and automation.
--all
Verify every repository tracked by DevSafe, not just one. Exits with code 1 if any repository fails.
--skip-restorability
Skip the git bundle verify step. Only checks the Merkle chain and AEAD tags. Faster, but does not prove the backup is actually restorable.

devsafe export-proof

Sometimes you need to prove a backup is valid to someone who does not have your encryption key. For example, an auditor, a compliance team, or a future version of yourself on a different machine.

devsafe export-proof creates a standalone verification proof that is decoupled from the backup lifecycle. The proof contains the Merkle root, chain metadata, and a cryptographic signature, but no encryption keys and no repository data.

terminal
$ devsafe export-proof api-server --out api-server-proof.json
 proof exported to api-server-proof.json
  repo: api-server
  bundles covered: 47
  chain root: a3f8c1...d902
  signed with: prod-2026 (public key embedded)
  proof format: v1

The exported proof file is small (typically under 10 KB) and safe to share. It contains no secrets.

--out <path>
Where to write the proof file. Defaults to <repo-id>-proof.json in the current directory.
--format <json|cbor>
Output format. JSON is human-readable. CBOR is compact and better for machine consumption.

devsafe verify-proof

Verifies a standalone proof file created by devsafe export-proof. This command needs only the proof file and the signer's public key. It does not need access to the backup, the encryption key, or the storage provider.

terminal
$ devsafe verify-proof api-server-proof.json --pubkey prod-2026.pub
 signature valid
 chain root: a3f8c1...d902 (47 bundles)
 proof timestamp: 2026-07-01T14:23:08Z
 VERIFIED: this proof was signed by the holder of prod-2026

This is useful for three scenarios:

--pubkey <path>
Path to the signer's public key file. If omitted, DevSafe checks ~/.devsafe/keys/ for a matching key.

devsafe server-verify

Runs verification on the server side (your user-owned storage) without needing the encryption key on the verifying machine. This checks the Merkle chain and bundle sequence, but cannot check AEAD authentication tags or git bundle restorability because those require decryption.

Server-verify is designed for monitoring. You can run it from a CI job, a cron schedule, or a separate machine to continuously confirm that your storage provider has not lost or corrupted any bundles.

terminal
$ devsafe server-verify api-server
→ checking bundle inventory (no decryption)...
→ found 47 bundles (sequence 001–047)
 sequence complete (no gaps)
 Merkle chain intact (47/47 links)
 all bundle sizes within expected range

 api-server: SERVER-VERIFIED
  note: AEAD and restorability checks require the encryption key
  run "devsafe verify api-server" for a full verification
Server-verify is not a substitute for full verification.

It confirms that your storage provider still has all the bundles in the right order. It cannot confirm that the contents are intact or restorable. Run a full devsafe verify periodically (weekly or monthly) to get complete assurance.

CI integration

You can run verification in a CI pipeline to catch storage problems automatically. Use --json for machine-readable output and check the exit code.

github actions
# .github/workflows/verify-backups.yml
name: Verify Backups
on:
  schedule:
    - cron: '0 6 * * 1'  # every Monday at 6am
jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - name: Install DevSafe
        run: curl -fsSL https://get.devsafe.com | sh
      - name: Server-verify all repos
        run: devsafe server-verify --all --json

Exit codes