diff --git a/README.md b/README.md index 96c170c..90f35b5 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,12 @@ relicario list # Sync with your git remote relicario sync +# Pack the vault into a single encrypted backup file +relicario backup export -o vault.relbak + +# Print a recovery QR for your image_secret (see "Recovery" below) +relicario recovery-qr generate + # Generate a random password relicario generate -l 32 ``` @@ -108,6 +114,25 @@ The embedding survives: This means your reference image can live on your Instagram, your personal website, or anywhere else. It's useless without your passphrase. +## Recovery: what if I lose my reference image? + +Without your reference image, the vault is undecryptable — that's the security model. But it also makes a lost or corrupted image a single point of failure. + +The mitigation is the **recovery QR**: a printable QR code that wraps your image secret behind a separate recovery passphrase you choose. If you ever lose access to the reference JPEG, scan or transcribe the QR, provide the recovery passphrase, and recover the 256-bit image secret. Combined with your normal vault passphrase, this restores access to the vault. + +```bash +# Print a recovery QR (after the vault is unlocked). +# You'll be prompted for a separate recovery passphrase. +relicario recovery-qr generate + +# Recover the image_secret from a stored QR payload. +relicario recovery-qr unwrap +``` + +The QR payload is an XChaCha20-Poly1305 envelope keyed by Argon2id over a domain-separated input (prefixed with `b"relicario-recovery-v1\0"`), so even if you reuse your vault passphrase as your recovery passphrase, the wrap key cannot collide with a vault master key. Both salt and nonce are freshly randomized per call, so two QRs printed from the same passphrase yield different bytes — the printed copy doesn't leak whether you've printed others. + +Recommended practice: print the QR, store it offline (safe, deposit box), and forget about it. The recovery passphrase is what protects the printed copy from being useful to someone who finds it. + ## Architecture ``` @@ -122,6 +147,8 @@ relicario/ │ │ ├── settings.rs # VaultSettings (retention, generator defaults, caps) │ │ ├── backup.rs # `.relbak` encrypted-backup envelope │ │ ├── device.rs # ed25519 device keys + revocation entries +│ │ ├── recovery_qr.rs # Paper-printable image_secret backup (XChaCha20-Poly1305 + Argon2id) +│ │ ├── import_lastpass.rs # LastPass CSV → typed items │ │ └── vault.rs # Encrypt/decrypt items, manifest, settings │ ├── relicario-cli/ # CLI binary: filesystem, git, terminal I/O │ ├── relicario-wasm/ # Thin wasm-bindgen wrapper for the browser extension @@ -206,6 +233,7 @@ The binary is at `target/release/relicario`. - [x] Typed items: Login, SecureNote, Identity, Card, Key, Document, TOTP - [x] Secure document storage (encrypted file attachments) - [x] Backup & restore (`.relbak` encrypted envelope) +- [x] Recovery QR (paper-printable image_secret backup with separate passphrase) - [x] LastPass CSV import - [x] Device authentication (ed25519 commit signing + pre-receive hook) - [ ] Import from Bitwarden / 1Password