Skip to content

Encryption

Coldrune encrypts every secret with AES-256-GCM using a two-level key hierarchy.

Master key (64 hex chars, from COLDRUNE_MASTER_KEY env var)

  ├── HKDF-SHA256 (info: "coldrune-kek")
  │   └── KEK (Key Encryption Key)
  │         └── encrypts per-secret DEKs

  └── HKDF-SHA256 (info: "coldrune-backup-key")
      └── Backup encryption key
            └── encrypts database backups

For each secret:

  1. A random 32-byte DEK (Data Encryption Key) is generated
  2. The secret value is encrypted with the DEK using AES-256-GCM
  3. The DEK is encrypted with the KEK using AES-256-GCM
  4. Stored: encrypted_value, nonce, encrypted_dek, dek_nonce

The master key never encrypts data directly. It derives the KEK and backup key through HKDF-SHA256.

openssl rand -hex 32

This produces a 64-character hex string (256 bits). Store it securely — losing the master key means losing all secrets.

If you suspect key compromise or want to rotate keys as a policy:

  1. Stop the server

    sudo systemctl stop coldrune
  2. Rotate

    # Generate a new key automatically
    coldrune server rotate-key --generate
    
    # Or provide a specific new key
    COLDRUNE_NEW_MASTER_KEY=$(openssl rand -hex 32) coldrune server rotate-key

    This re-encrypts all DEKs with the new KEK in a single atomic transaction. Secret values and their nonces are unchanged — only the DEK encryption is rotated.

  3. Update COLDRUNE_MASTER_KEY in your .env file with the new key (printed to stdout)

  4. Restart the server

    sudo systemctl start coldrune
  5. Create a new backup — old backups are encrypted with the old key

ComponentChanged?
Master keyYes (new value)
KEKYes (derived from new master key)
Each DEK’s encryptionYes (re-encrypted with new KEK, fresh nonces)
Secret valuesNo (encrypted data unchanged)
Backup keyYes (derived from new master key)
Existing backupsNo (still encrypted with old key)

AES-GCM includes an authentication tag. Any modification to the ciphertext, nonce, or DEK causes decryption to fail. Coldrune does not silently return corrupted data.