Skip to content

Sealing and keys

The server holds some data that it can read: the values of server-readable spaces, TOTP secrets and similar items. It encrypts this data in the database. This page shows how that works and how to choose the key provider.

End-to-end encrypted folders are a different case. The server never has their keys. See Security.

The key hierarchy

    flowchart TD
  S["Unseal secret<br/>(passphrase or key file)"] -->|"Argon2id, or read raw"| K["KEK<br/>key encryption key"]
  K -->|"unwraps"| D["Data key<br/>(random, in memory only)"]
  D -->|"encrypts"| V["Server-readable values<br/>TOTP secrets, op values"]
  W[("meta: seal.data_key<br/>wrapped data key")] --> K
  
  • The server has one random data key. It encrypts all server-readable values.
  • A key encryption key (KEK) wraps the data key. The wrapped data key is in the meta table of the database.
  • A key provider supplies the KEK from the unseal secret.
  • The data key is in memory only. The server does not keep the KEK after the start.

Sealed and unsealed

  • Sealed: the server has no data key. The database file is only ciphertext for these values.
  • Unsealed: the server unwrapped the data key at start. It can read and write server-readable values.

lasboltd unseals at start and does not listen before that. If the unseal fails, the program stops with an error. So a running server is always unsealed, and lasboltctl status shows state: unsealed. There is no command to seal a running server or to unseal it later. Stop the service to seal it.

Key providers

ProviderFlagWhere the KEK comes from
passphrase (default)--key-provider passphraseArgon2id of an operator passphrase. The passphrase comes from the terminal, or from the file in --unseal-passphrase-file.
file--key-provider file --key-file PATH32 raw bytes in a file.
insecure-static--dev onlyA fixed key that is public in the source code. For tests.

Passphrase from the terminal

Start lasboltd in a terminal. On the first start it asks for the passphrase twice. At each later start it asks once. The passphrase is never on the disk of the server. The service cannot restart by itself after a reboot, because nobody types the passphrase. Use this for a server that a person watches.

Passphrase from a file

head -c 32 /dev/urandom | base64 > /etc/lasbolt/passphrase
chmod 600 /etc/lasbolt/passphrase

Set LASBOLT_UNSEAL_PASSPHRASE_FILE=/etc/lasbolt/passphrase. The server removes one trailing newline. A service restarts by itself. The cost: a person who can read the disk of the server has the passphrase and the database.

Key file

head -c 32 /dev/urandom > /etc/lasbolt/kek
chmod 400 /etc/lasbolt/kek

Set LASBOLT_KEY_PROVIDER=file and LASBOLT_KEY_FILE=/etc/lasbolt/kek. The file must hold exactly 32 bytes. This has the same property as a passphrase file, and no Argon2id step. Use it when the file comes from a secret store at deploy time (see Deploy with Ansible).

Rules for secret files

  • The file must not be readable by group or others. The server refuses a file with a wider mode, and names the file in the error.
  • A wrong secret stops the start with cannot unseal: wrong passphrase or key.
  • The provider is not stored in the database. You must start with the provider that made the data key. A passphrase on a database that a key file sealed gives the same error.
  • The passphrase is not a user master password. The server never gets a user password.

What each choice protects against

ThreatTerminal passphrasePassphrase file or key file
Someone steals a disk, a snapshot or a backupProtected. A guess of the passphrase costs Argon2id time for each try.Protected, if the secret file is not on the same disk or snapshot.
Someone with root on the running hostNot protected. The data key is in memory.Not protected.
Someone who can read the files of the host, with the server stoppedProtectedNot protected: the secret file is next to the data.
The host reboots at nightThe service waits for a person.The service starts by itself.
Lost secretData cannot be opened. There is no reset.Data cannot be opened. There is no reset.

Notes:

  • A passphrase is only as strong as it is long. A person who gets the database or a backup can guess offline. Use a long random passphrase.
  • Seal your backups to a separate key. Then a copy of a backup does not give a chance to guess the passphrase. See Backups and restore.
  • A key file or passphrase file keeps the data safe from a lost disk only when the secret is on another medium, for example a secret store that the deploy tool reads. A deploy tool that puts the secret on the same disk gives protection from a stolen backup, not from a stolen host.
  • The secret can only be changed by a deploy of the same value. There is no command to change the passphrase or the KEK of an existing database. Not available yet.

Keep the secret

Store the passphrase or the key file in two places away from the server, for example a password manager and a sealed envelope. Test that the stored copy opens a backup. See “Test the restore” in Backups and restore.

Last updated on