Your password never leaves your device
Traditional password managers hash your master password and send it to a server for verification. The server stores something derived from your password, and a determined attacker could try to reverse it.
Grippy uses OPAQUE (RFC 9807), an asymmetric password-authenticated key exchange. Your password is blinded using a Ristretto255 oblivious PRF and stretched through Argon2id with 64 MiB of memory, entirely on your device. The server participates in the exchange but never sees your password, a hash of it, or anything that could be used to guess it.
Even if an attacker captured every byte of traffic between you and our servers, they'd gain nothing useful. OPAQUE produces only cryptographic proofs that are meaningless without the original password. No hash, no derived key, no password equivalent ever crosses the wire.
Encrypted before it leaves, unreadable until it returns
After OPAQUE authentication, your device derives a Key Encryption Key (KEK) from the protocol's export key using BLAKE3. This KEK protects your Data Encryption Key (DEK), a 32-byte random value generated on your device during registration. The KEK exists only in memory and is cryptographically erased when your session ends.
Every vault entry is encrypted with XChaCha20-Poly1305 using the DEK. Each encryption uses a fresh 192-bit random nonce, and every ciphertext is bound to its field type, record, and user through authenticated associated data, so even with database access, an attacker can't swap encrypted fields between entries or users.
We never hold your KEK, your DEK, or the export key they derive from. If a court ordered us to hand over your vault, all they'd get is ciphertext that's computationally infeasible to break.
Every request earns its way in
Before our server processes any API call, authenticated or not, your device must solve an Equix proof-of-work puzzle. Each challenge is derived from the server secret and the specific endpoint, so a solution for one request can't be reused against another.
For a real user this takes milliseconds and happens invisibly. For an attacker attempting credential stuffing, brute force, or denial of service, the computational cost makes the attack economically impractical at scale.
Checking without exposing
Grippy checks your credentials against known breach databases, but it never sends your actual passwords or email addresses to the checking service. Instead it uses k-anonymity, a technique where only a small prefix of a hash is sent and the service returns all matching entries.
Your device then checks locally whether any of them match. The service never knows what you were looking for, and your data stays private even during the security check.
The foundation matters too
The entire backend is written in Rust, eliminating buffer overflows, use-after-free, and data races at compile time. All key material is wrapped with Zeroize, guaranteeing sensitive bytes are overwritten in memory the moment they're no longer needed. The desktop app uses Tauri instead of Electron, so no embedded Chromium, smaller attack surface, native performance.
Every authenticated request is signed with a BLAKE3 keyed MAC derived from the OPAQUE session key. Each signature includes a unique nonce tracked in Redis, a timestamp checked within a 60-second window, and a body hash, making replay attacks, request tampering, and timing manipulation all detectable. Session tokens use PASETO v4, a modern format designed to prevent the implementation mistakes that plague JWT.
What we see vs. what we don't
We can see
- Encrypted vault blobs
- Account metadata (creation date, plan type)
- Encrypted session tokens
We can never see
- Your master password
- Your vault contents
- Your encryption keys
- Individual passwords or entries