Skip to content

ADR: Use sealed box encryption for credentials-at-rest#

Status#

Implemented

Context#

Drupal CMS and the wider AI Initiative identified insecure patterns for storing provider credentials, including storing secrets in configuration in ways that make them easy to leak via configuration export, repository access, or operational mistakes.

Easy Encryption was created to provide a secure-by-default credential storage mechanism with minimal configuration and a workflow friendly to configuration management. In particular, the design goal was to support a model where encryption can happen broadly (for example during development, CI, or when a site builder enters a value), while decryption can be restricted to specific environments.

The design choice came down to two main libsodium approaches: - Secret box (symmetric encryption) where the same secret key must be available anywhere encryption or decryption is needed. - Sealed box (public-key encryption for a recipient) where encryption requires only a public key, and decryption requires the private key.

Decision#

Use libsodium sealed box encryption (crypto_box_seal / crypto_box_seal_open) as the primary mechanism for encrypting credentials stored via the module’s Key provider.

Store the public key in configuration (exportable), and keep the private key out of version control and restricted to environments that are allowed to decrypt.

Alternatives#

  • Secret box (crypto_secretbox_*):
  • Symmetric encryption, requires distributing the same secret key to any environment that needs to encrypt or decrypt.
  • Nonce-based public-key box (crypto_box_easy / crypto_box_open_easy):
  • Requires explicit nonce generation and storage in the ciphertext format.
  • Using existing encryption solutions with heavier configuration:
  • Potentially more flexible, but not aligned with the “secure by default, minimal configuration” requirement.

Consequences#

Benefits#

  • Supports the workflow “encrypt with a public key anywhere, decrypt only where the private key is present”.
  • Reduces accidental secret sharing because the public key can be exported and committed safely while the private key remains restricted.
  • Reduces cryptography foot-guns in a module meant to be easy to adopt and safe by default.

Drawbacks#

  • If the key material is incomplete (for example, public key missing or corrupted), existing encrypted credentials may become inaccessible and require operational recovery (restoring keys from backup or re-encrypting).
  • Rotation requires dedicated tooling and careful UX, because existing encrypted data may reference older key IDs and needs a controlled migration path.

Notes#

Sealed box is a good fit when the module does not need to prove or record “who encrypted” a value, and the primary requirement is recipient-based encryption with a public key and restricted decryption with a private key.

Authors#

  • Dezső Biczó (@mxr576)

Date#

2025-12-10