Skip to content

Encryption model

Cove uses a server-trusted model. This page spells out exactly what that means.

  1. Master password (security.master_password): generated on first start if empty, or supplied via COVE_MASTER_PASSWORD.
  2. Key-encryption key (KEK): derived from the master password with Argon2id.
  3. Data-encryption key (DEK): encrypts the BadgerDB database at rest. It is stored wrapped by the KEK.
  4. Channel keys: each channel has a unique AES-256 key, generated by the server, stored wrapped by the KEK and sent to authorized members over their authenticated connection.

Clients encrypt messages with the channel key (AES-256-GCM) before sending. The server stores and routes ciphertext. Because the server holds the channel keys, the operator of the server can decrypt messages. This is deliberate: it makes multi-device sign-in, history and account recovery work without a key-verification ritual.

  • A stolen disk or database backup (data is encrypted at rest and useless without the master password)
  • Network eavesdropping (use HTTPS in front of the server)
  • Other users reading channels they are not members of
  • A malicious or compromised server operator
  • Someone with both the database and the master password

WebRTC media is encrypted hop by hop with DTLS-SRTP between each client and the SFU. The SFU forwards media, so it is not end-to-end encrypted. Raw UDP mode is not encrypted at all and is meant for trusted LANs.

Use Whisper for conversations where the server must not be able to read or retain anything.

Browsers use an httpOnly cove_session cookie plus a double-submit CSRF token (cove_csrf cookie echoed in the X-CSRF-Token header). The desktop app uses a Bearer token instead. Passwords are hashed with Argon2id.