Skip to content

feat: add direct AWS KMS encryption for cardholder data#163

Open
BenJanecke wants to merge 1 commit intojuspay:mainfrom
peach-payments:feat/kms-encryption
Open

feat: add direct AWS KMS encryption for cardholder data#163
BenJanecke wants to merge 1 commit intojuspay:mainfrom
peach-payments:feat/kms-encryption

Conversation

@BenJanecke
Copy link
Copy Markdown

@BenJanecke BenJanecke commented Mar 24, 2026

Summary

#162

Adds a new aws_kms mode for the external_key_manager config that delegates all cardholder data encryption to AWS KMS — no encryption keys are ever generated, stored, or handled locally. This shifts
cryptographic key management responsibilities to AWS KMS (a PCI DSS Level 1 validated service), significantly reducing the operator's PCI compliance scope and audit surface for key management controls.

  • Implements KmsKeyManager / KmsCryptoManager behind the existing KeyProvider / CryptoOperationsManager trait abstraction, requiring zero changes to route handlers
  • Uses KMS encryption context to cryptographically bind ciphertext to each entity, preventing cross-entity decryption
  • Refactors AwsKmsClient to a single encrypt/decrypt API operating on raw bytes with optional encryption context; base64/UTF-8 handling moved to the SecretManager impl
  • All new code gated behind the existing kms-aws feature flag with no new dependencies

Configuration

[external_key_manager]
mode = "aws_kms"

[tenant_secrets.my_tenant]
master_key = "unused_placeholder"
schema = "my_tenant"

[tenant_secrets.my_tenant.kms_data_key]
key_id = "arn:aws:kms:us-east-1:123456789:key/abcd-1234"
region = "us-east-1"

Test plan

  • cargo build (default features) — compiles, KMS code fully gated
  • cargo build --features kms-aws — compiles with KMS support
  • cargo clippy --all-features --all-targets — no new warnings
  • cargo test — all existing tests pass
  • Deploy with aws_kms mode against a real KMS key, verify encrypt → store → retrieve → decrypt round-trip
  • Verify encryption context binding: attempt decrypt with wrong entity_id fails

Allow cardholder data to be encrypted/decrypted directly by AWS KMS,
eliminating all local key material. A new `aws_kms` mode for
`external_key_manager` routes encrypt/decrypt calls through the KMS
Encrypt/Decrypt APIs with per-entity encryption context binding.

Also refactors AwsKmsClient to use a single encrypt/decrypt API that
operates on raw bytes, moving base64/UTF-8 concerns to the SecretManager
implementation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant