This document describes the security architecture of zault.
- Offline attacks - Attacker has access to the vault file
- Memory dumps - Attacker can read process memory
- Clipboard sniffing - Malware monitoring clipboard
- Shoulder surfing - Attacker can see your screen
- Compromised system - Keyloggers, rootkits
- Physical access - Attacker with physical device access
- Rubber hose cryptanalysis - Coercion
flowchart TB
MP[Master Password] --> Argon2
Salt[Salt - 32 bytes random] --> Argon2
subgraph Argon2["Argon2id"]
Params["Memory: 64MB | Iterations: 3 | Parallelism: 4"]
end
Argon2 --> MK[Master Key - 32 bytes]
Why Argon2id?
- Memory-hard: Resistant to GPU/ASIC attacks
- Side-channel resistant (unlike Argon2i)
- Winner of Password Hashing Competition
- OWASP recommended
flowchart TB
MK[Master Key] --> XChaCha
Nonce[Nonce - 24 bytes random] --> XChaCha
Plaintext[Vault Data] --> XChaCha
subgraph XChaCha["XChaCha20-Poly1305"]
AEAD[Authenticated Encryption]
end
XChaCha --> Ciphertext[Encrypted Vault]
XChaCha --> Tag[Auth Tag - 16 bytes]
Why XChaCha20-Poly1305?
- AEAD: Encryption + authentication in one
- 24-byte nonce: Safe for random generation
- No padding oracle attacks
- Constant-time implementation
- RFC 6238 compliant
- Supports SHA-1, SHA-256, SHA-512
- Secrets stored encrypted in vault
- Ed25519 or ECDSA P-256 key pairs
- Private keys encrypted in vault
- Challenge-response with origin validation
- Locked memory - Secrets allocated with
mlock()to prevent swapping - Zeroing - All sensitive data zeroed before deallocation
- No GC - Zig has no garbage collector, giving us deterministic memory control
- Minimal copies - Secrets are not copied unnecessarily
block-beta
columns 1
block:heap["Process Memory"]
regular["Regular Heap"]
block:locked["Locked Pages (mlock)"]
mk["Master Key"]
entries["Decrypted Entries"]
totp["TOTP Secrets"]
end
end
- Auto-clear - Clipboard cleared after 45 seconds (configurable)
- No history - We attempt to prevent clipboard managers from recording
packet-beta
0-31: "Magic: ZAUL"
32-47: "Version: u16"
48-95: "KDF Params"
96-351: "Salt (32 bytes)"
352-543: "Nonce (24 bytes)"
544-799: "..."
800-1055: "Ciphertext (variable)"
1056-1183: "Auth Tag (16 bytes)"
| Section | Size | Description |
|---|---|---|
| Header | 96 bytes | Unencrypted metadata |
| Magic | 4 bytes | "ZAUL" identifier |
| Version | 2 bytes | Format version |
| KDF params | varies | Argon2 parameters |
| Salt | 32 bytes | Random salt |
| Nonce | 24 bytes | XChaCha20 nonce |
| Ciphertext | variable | Encrypted entries |
| Auth Tag | 16 bytes | Poly1305 tag |
- Use a strong master password (20+ characters, or passphrase)
- Enable disk encryption on your device
- Keep zault updated
- Lock vault when not in use
- Use the password generator
- Never log sensitive data
- Use secure allocator for all secrets
- Constant-time comparisons for secrets
- Fuzz all parsing code
- Review all crypto usage
This project has not been professionally audited. Use at your own risk.
If you'd like to sponsor a security audit, please open an issue.
Please report security vulnerabilities privately via GitHub Security Advisories.
Do not open public issues for security vulnerabilities.