Skip to content

[Feature] Per-entity envelope-encrypted state with KEK rotation #223

Description

@pathosDev

Size / Priority

  • Size: L — touches encryption infrastructure.

Rationale

Current encryption (src/persistence/object-storage/Encryption.ts) uses a single bucket-wide master key. All entity state encrypted with the same key family.

Stronger model: per-entity envelope encryption:

  • Each entity has a unique Data Encryption Key (DEK).
  • DEKs wrapped by the master Key Encryption Key (KEK).
  • KEK rotation: rewrap DEKs; entity state unchanged.

Benefits:

  • KEK rotation faster (only DEK wrappers change; entity payloads stay).
  • Smaller blast radius (DEK leak ≠ master-key leak).
  • Per-tenant key isolation if DEK is per-tenant.

Design sketch

// src/persistence/encryption/EnvelopeEncryption.ts (new)

export interface EnvelopeEncryptionConfig {
  readonly kek: KeyEncryptionKey;        // master, rotatable
  readonly dekStore: DekStore;            // where wrapped DEKs live
}

export interface KeyEncryptionKey {
  readonly id: string;
  wrap(dek: Uint8Array): Promise<Uint8Array>;
  unwrap(wrappedDek: Uint8Array): Promise<Uint8Array>;
}

export interface DekStore {
  load(persistenceId: string): Promise<{ wrapped: Uint8Array; kekId: string } | undefined>;
  save(persistenceId: string, wrapped: Uint8Array, kekId: string): Promise<void>;
}

// PersistentActor opts in:
class MyActor extends PersistentActor<...> {
  override encryptionConfig(): EncryptionConfig {
    return { mode: 'envelope', envelope: this.system.extension(EnvelopeEncryptionId) };
  }
}

KEK rotation: rewrap all DEKs (sweep similar to existing master-key sweep).

Integration

Out of scope / non-goals

  • HSM integration — pluggable via KEK interface; user provides HSM-backed KEK.
  • Per-record DEK (each event has its own) — phase 1 per-entity only.

Open design questions

  1. DEK storage: alongside journal vs separate store. Recommend separate (DekStore interface).
  2. First-write DEK generation: when does the DEK first get created? On first persist. Document.
  3. Old-DEK retention during rotation: keep until sweep complete.

Test plan

  1. Encrypt event with per-entity DEK; decrypt round-trip.
  2. KEK rotation: rewrap; old entities still decrypt.
  3. DEK leak doesn't compromise other entities.
  4. Per-tenant DEK scoping.

Acceptance criteria

  • EnvelopeEncryption + KEK/DEK interfaces.
  • DEK store implementations.
  • KEK rotation sweep.
  • Documentation.
  • Test suite.
  • CHANGELOG entry.

Pre-implementation checklist

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowNice-to-have / niche / demand-driven

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions