Skip to content

feat: support direct AWS KMS encryption for cardholder data #162

@BenJanecke

Description

@BenJanecke

Problem

The vault currently generates and manages its own encryption keys (per-merchant AES-256-GCM DEKs encrypted by a tenant master key). This means sensitive key material exists in the vault's memory and database,
placing the full burden of cryptographic key management under PCI DSS scope key generation, rotation, storage, access control, and destruction must all be documented, audited, and maintained by the operator.

By delegating key custody to AWS KMS, these responsibilities shift to an AWS service that is already validated as a PCI DSS Level 1 Service Provider. This significantly reduces the operator's PCI compliance scope
and audit surface for key management controls.

Proposed Solution

Add a new aws_kms mode for the external_key_manager configuration that calls the AWS KMS Encrypt and Decrypt APIs directly for cardholder data. In this mode:

  • No encryption keys are generated, stored, or handled by the vault — AWS KMS has full custody
  • Key lifecycle management (rotation, access control, audit logging) is handled entirely by AWS KMS, covered under AWS's own PCI DSS certification
  • Per-entity encryption context binds ciphertext to the merchant, preventing cross-entity decryption
  • Per-tenant KMS key IDs allow different tenants to use different AWS KMS keys

This slots into the existing KeyProvider / CryptoOperationsManager trait abstraction, requiring no changes to route handlers or the storage layer.

Constraints

  • AWS KMS Encrypt has a 4KB plaintext limit (card data payloads are well under this)
  • Each encrypt/decrypt is a network call to AWS KMS, adding latency vs local AES-GCM
  • AWS KMS request quotas apply (5,500–30,000 req/s per key depending on region)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions