Security model
This page describes what Rempar protects, how, and what it does not protect. The reference document is protocol v1, whose strings are frozen.
Goal
A complete compromise of the server, its backups and its administrator must reveal no secret: not the master password, not the content, not even the name of an item.
Key derivation (device only)
password = NFKC(input)
master_key = Argon2id(password, kdf_salt, m=65536 KiB, t=3, p=4, 32 bytes)
auth_key = HKDF-SHA256(master_key, info="rempart/auth/v1")
wrap_key = HKDF-SHA256(master_key, info="rempart/wrap/v1")
kdf_salt: 16 random bytes, created with the account or the local vault.auth_keyis sent to the server as the account password. It cannot be used to derive anything else.wrap_keynever leaves the device. It seals the vault key.- Clients refuse Argon2id parameters weaker than m=19456, t=2, p=1, even if the server offers them.
Sealing format
seal(key, plaintext, aad) = base64( 0x01 || nonce(24) || XChaCha20-Poly1305(key, nonce, plaintext, aad) )
Each use has its own frozen AAD string: rempart/vaultkey/v1, rempart/itemkey/v1|<item_id>, rempart/item/v1|<item_id>, rempart/export/v1, etc. A blob cannot be replayed in another context or attached to another item.
Vault and items
vault_key: 32 random bytes, created once per vault.- Each item has its own 32-byte
item_key. The stored blob is{ k: seal(vault_key, item_key), c: seal(item_key, content) }. - The list is displayed from a local sealed index. Opening an item only decrypts that item.
- Item identifiers are UUID v4, bound in both AADs.
Recovery kit
32 random bytes, shown once only in Crockford base32. recovery_wrap = HKDF(recovery_key, "rempart/recovery-wrap/v1") seals a copy of the vault key; recovery_auth = HKDF(recovery_key, "rempart/recovery-auth/v1") authenticates a restoration with the server.
Account and tokens
- Anti-enumeration pre-login: a deterministic dummy salt is returned for unknown e-mail addresses.
- Per-device access token (60 min) and rotating refresh token (30 days). A second use of a rotated refresh token revokes the device (
token_reused). - Optional TOTP 2FA, recommended. Mandatory for administrators.
- All sensitive routes are rate-limited.
On the device
- Secrets hidden behind 12 fixed dots, hidden again after 30 s.
- Clipboard cleared after 30 s (adjustable from 10 s to 2 min). Recovery phrases are never copied as a whole.
- Lock after 5 min, on sleep and on close; the vault key is zeroed in memory.
- Progressive delays after failure: 30 s, 1 min, 5 min. Never any silent wipe.
- Android:
FLAG_SECUREprevents screenshots. iOS and macOS: privacy veil in the app switcher. - Biometrics: the vault key is entrusted to the system keychain protected by Touch ID, Face ID or fingerprint, never to a file.
What the model does not cover
- A device compromised while the vault is open (spyware, keylogger).
- A weak master password: Argon2id slows the attack down, it does not make it impossible.
- The simultaneous loss of the master password and the recovery kit.
- Account metadata: e-mail address, number of items, blob sizes, device dates and platforms.
Reporting a vulnerability
Write to security@rempar.org. We acknowledge receipt within 48 hours and publish a fix before any disclosure.
A question not answered here? support@rempar.org