TessariDBDocs
  • 0.34.2-betalatest
  • 0.34.1-beta
  • 0.34.0-beta
  • 0.33.4-beta
  • 0.33.3-beta
  • 0.33.2-beta
  • 0.33.1-beta
  • 0.33.0-beta
  • 0.32.0-beta

Encryption at rest

One key file encrypts every file the store writes and seals every backup; a store opens only the way it was created, and moving to a new key is a backup and a restore.

From 0.21.0-beta a store can be encrypted under a key you hold. It is opt-in: a store created without a key is not encrypted, and stays that way.

openssl rand 32 > store.key && chmod 600 store.key
tessaridb ./data --encryption-key-file store.key --serve 0.0.0.0:9080

TESSARIDB_ENCRYPTION_KEY_FILE stands for the flag, which is how a container is given it. The file holds exactly 32 bytes and, on Unix, must not be readable by its group or by others; any other file is refused, saying which check failed:

the encryption key file store.key: may be read by others (mode 644); `chmod 600` it

What is encrypted

Given a key, a node encrypts every file its storage engine writes — the tables, the write-ahead log, the manifest, the engine's own options and log — and seals every backup it produces: a snapshot, a log or a script, whether it is answered by BACKUP, written by BACKUP … TO, streamed by GET /backup, or written by --backup, --snapshot and --dump.

The key is never used as it is. Three subkeys are drawn from it: one for the engine's files, one for backups, and one for a marker file, ENCRYPTION, that records which key the store was created under. The engine's files are XChaCha20 with a random nonce per file, and their integrity is the engine's own checksums. A sealed backup is ChaCha20-Poly1305 in 64 KiB chunks, each bound to its position and to whether it is the last, so a backup cut short, reordered, extended or altered does not open.

A store opens only the way it was created

The node says which way is wrong before the engine reads anything:

openedanswer
an encrypted store, with no keythe store at ./data is encrypted; it opens only with its key
an encrypted store, under another keythe encryption key does not open the store at ./data: it was encrypted under another key
a plain store, given a keythe store at ./data is not encrypted, and an encryption key was given

A sealed backup opens only where its key is

RESTORE SCRIPT FROM, --restore and --verify open a sealed backup with the node's key. Without one it is refused — this backup is sealed; it opens only on a node given its encryption key — and under another key it does not open either. A plain backup still restores into an encrypted store.

tessaridb --encryption-key-file store.key --verify state.tessarisnap

Moving to a new key

Nothing rewrites a store in place. A store moves to a new key by a backup, and a restore of that backup into a new store under the new key — --backup-key-file names the key the backup was sealed under when it is not the new store's:

tessaridb ./data --encryption-key-file old.key --backup state.tessarisnap
tessaridb ./renewed --encryption-key-file new.key \
          --backup-key-file old.key --restore state.tessarisnap

A lost key is a lost store and a lost set of backups. Keep it somewhere the store is not — in a container, a secret mount rather than the store's volume.

What it protects, and what it does not

The disk and the backups: a stolen volume, a discarded drive, a backup file left in a bucket. Not a running node — it holds the key in memory and answers anyone with a credential, and privileged code on the host can read both — and not the traffic, which is Encryption in transit.

whereholdsencrypted
the store's directoryevery record, the catalog, the logyes, under the engine subkey
ENCRYPTIONa sealed constant that says which keyholds no data
a backup file, wherever it is copiedevery record of its partsealed, under the backup subkey
<name>.partial while BACKUP … TO writesthe samesealed
the node's temporary folder while GET /backup spoolsthe samesealed
the key filethe keyno — keep it apart from the store
the node's memoryeverything it has readno
the node's own log lines on standard errorevents and failure reasons, which can name a table or an idno

A vault keeps its sealed values sealed under its own key whether or not the store is encrypted; the two are separate keys with separate custody.

Encryption at rest — TessariDB