Skip to content

feat(backend): field-level encryption for PII data (Claim & VerificationSession)#212

Merged
Cedarich merged 2 commits intoPulsefy:mainfrom
BigBen-7:feat/209-field-level-encryption-pii
Mar 29, 2026
Merged

feat(backend): field-level encryption for PII data (Claim & VerificationSession)#212
Cedarich merged 2 commits intoPulsefy:mainfrom
BigBen-7:feat/209-field-level-encryption-pii

Conversation

@BigBen-7
Copy link
Copy Markdown
Contributor

Summary

Closes #209

Implements Privacy by Design field-level encryption for sensitive PII stored in PostgreSQL, using Node's built-in crypto module (no external dependencies added).

  • EncryptionService (src/common/encryption/) — two encryption strategies:
    • encrypt / decrypt — AES-256-GCM with random IV (non-deterministic, authenticated). Used for Claim.recipientRef and VerificationSession.code.
    • encryptDeterministic / decryptDeterministic — AES-256-CBC with HMAC-derived fixed IV. Used for VerificationSession.identifier so equality-based DB lookups (rate-limiting count query) continue to work.
  • EncryptionModule — NestJS module that provides and exports EncryptionService; imported into ClaimsModule and VerificationModule.
  • ClaimsService — encrypts recipientRef on create(); decrypts on findOne(), findAll(), and before passing to the on-chain adapter in disburse().
  • VerificationFlowService — encrypts identifier (deterministic) and code on start() and resend(); decrypts identifier before sending OTP, decrypts code before comparing in complete().
  • Master key controlled via ENCRYPTION_MASTER_KEY env var (documented in .env.example); warns at startup if unset.
  • Unit tests — 10 tests covering round-trips, non-determinism, determinism, tamper detection, and edge cases; existing test suites updated with identity-mock EncryptionService so all prior assertions remain green.

Test plan

  • EncryptionService unit tests pass (encryption.service.spec.ts — 10/10)
  • No lint errors (0 errors, warnings only — all pre-existing)
  • No new TypeScript errors introduced
  • Existing ClaimsService and VerificationFlowService test mocks updated with identity-mock encryption so prior assertions are unaffected
  • CI pipeline: lint → test → build (all steps pass once pnpm install runs prisma generate)

…icationSession)

Implements AES-256-GCM/CBC encryption for sensitive recipient metadata
before persistence, per Privacy by Design principles (issue Pulsefy#209).

- Add EncryptionService with encrypt/decrypt (AES-256-GCM, random IV)
  and encryptDeterministic/decryptDeterministic (AES-256-CBC, fixed IV)
  driven by ENCRYPTION_MASTER_KEY env variable
- Add EncryptionModule exported for use across feature modules
- Encrypt Claim.recipientRef on create; decrypt on findOne/findAll/disburse
- Encrypt VerificationSession.identifier (deterministic, for rate-limit
  queries) and VerificationSession.code (non-deterministic) on write;
  decrypt on read before sending OTP and code comparison
- Update ClaimsModule and VerificationModule to import EncryptionModule
- Add identity-mock EncryptionService to existing test suites so all
  prior assertions continue to pass without modification
- Add comprehensive unit tests for EncryptionService (encrypt/decrypt
  round-trips, determinism, tamper detection, edge cases)
- Document ENCRYPTION_MASTER_KEY in .env.example with generation guide
@drips-wave
Copy link
Copy Markdown

drips-wave bot commented Mar 27, 2026

@BigBen-7 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copy link
Copy Markdown
Contributor

@Cedarich Cedarich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Cedarich Cedarich merged commit 22de8fb into Pulsefy:main Mar 29, 2026
1 check passed
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.

Field-Level Encryption for PII Data (Recipient Metadata)

2 participants