ADR-020: Master key request-lifetime caching 

Table of contents

Status 

Accepted

Date 

2026-03-28

Context 

Master key providers re-read the key material from disk, environment variables, or re-derived it via HKDF on every decrypt operation. In requests that decrypt multiple secrets (e.g., frontend rendering with several vault-backed content elements), this caused repeated filesystem reads or HKDF computations for the same key material.

The master key does not change within a single HTTP request, so repeated derivation is pure overhead.

Decision 

Cache the derived master key in memory for the lifetime of the current request:

  • On first access, the master key provider reads/derives the key and stores it in a private property.
  • Subsequent decrypt operations within the same request reuse the cached key without additional I/O or derivation.
  • On object destruction (end of request), the cached key material is securely wiped using sodium_memzero() to prevent it from lingering in process memory.

This follows the principle of minimizing key material exposure: the key exists in memory only for the duration of the request and is actively cleared rather than left for garbage collection.

Consequences 

Positive 

  • One key derivation per request instead of per-decrypt, eliminating redundant I/O and HKDF computations.
  • Secure cleanup: sodium_memzero() on destruct ensures key material does not persist in memory beyond the request.
  • Transparent: No API changes; callers are unaware of the caching.

Negative 

  • Memory residency: The master key remains in process memory for the full request duration rather than being immediately discarded after each use.
  • Destructor dependency: Relies on PHP object lifecycle for cleanup; long-running processes (e.g., workers) must ensure timely destruction.