Security
Threat model · v1.0 · 2026-05-09
This page is the short version. The exhaustive document lives in SECURITY.md in the repository, alongside the audit log of cryptographic decisions.
What zz-drop protects
- Your profile at rest. Profile files (
~/.config/zz-drop/profiles/*) are sealed with XChaCha20-Poly1305 using a 256-bit key derived from your passphrase via Argon2id. The v1 baseline is m=64MiB, t=3, p=1; this is rotated upward when the maintainer ships a new default — see the parameter-rotation note in the repository. - Your passphrase. Stays in memory only as long as needed; zeroized on drop. Never written to disk in plaintext, never sent over the network.
- Your OAuth tokens. Stored only inside the encrypted profile. A leaked, decrypted profile would give an attacker the same access the provider's own client would.
- HTTPS to providers and to zz-drop.net. rustls with the operating system trust store (Security.framework on macOS, the system CA bundle on Linux — zz-drop ships Unix-only; Windows is supported via WSL, which uses the Linux trust store). zz-drop trusts the same set of issuers your browser does. There is no
--insecureflag; an unverifiable certificate is a hard failure. Behind a corporate TLS-inspection proxy: install the corp CA in the system trust store, or exportSSL_CERT_FILE=/path/to/corp-ca.pemto pin the trust set to that PEM only. If that variable is set but unreadable or empty, zz-drop fails closed rather than falling back to the system trust store.
What zz-drop does not protect — yet
- File content in flight to the provider. v1 uploads file bytes as-is over TLS to the four active providers. They see plaintext exactly as their first-party clients would.
- File content at rest with the provider. Same caveat. Provider-side encryption depends on the provider.
- End-to-end encryption of file content is on the v1.1 roadmap. We will not ship it before it has been independently reviewed.
Out of scope
- Compromised endpoint (your machine, after passphrase entry, while profile is unlocked).
- Coercion against you or the cloud provider operator.
- Cryptographic primitives themselves; we trust the upstream Rust crypto crates that wrap these primitives (chacha20poly1305, argon2) and the RustCrypto / sodiumoxide ecosystems they depend on.
Verifying release artifacts
Every release artifact on GitHub — per-platform tarballs and the zz-drop-installer.sh shell installer — is signed with minisign. Each artifact ships alongside a matching .minisig signature file. Verify before installing:
BASE=https://github.com/zz-drop/zz-drop/releases/latest/download
curl -fsSLO $BASE/zz-drop-installer.sh
curl -fsSLO $BASE/zz-drop-installer.sh.minisig
minisign -Vm zz-drop-installer.sh -P RWQIGvqA37VpcZcJanzhRYdOzbcQAl4jAVcBIBRQ5WmjEHcZBZbiRSyA
sh zz-drop-installer.sh
The same public key signs the per-platform tarballs (zz-drop-aarch64-apple-darwin.tar.xz, etc.). The canonical copy of the key lives in the repository as release-key.pub.
Public key
The same key signs every release tarball and the shell installer. Key rotation, if it ever happens, will be announced via a signed advisory in the repository and a new key published here with a 30-day overlap.
Reporting a vulnerability
Email security@zz-drop.net. PGP fingerprint and disclosure window are in SECURITY.md. We aim to acknowledge within 72 hours and ship a fix within 30 days for severity high or critical.