Developer Implementation Guide

Table of Content

Table of Content

Table of Content

Encrypt data and manage keys securely

Encrypt sensitive data in transit and at rest, separate keys from data, and control key use through a managed KMS. Use modern, authenticated ciphers, rotate keys on a schedule, and make every cryptographic operation auditable.

Encrypt Data and Manage Keys Securely

Encrypt sensitive data in transit and at rest, separate keys from data, and control key use through a managed KMS. Use modern, authenticated ciphers, rotate keys on a schedule, and make every cryptographic operation auditable.

Scope and Strategy

  • Classify data and decide what needs field-level, record-level, and volume-level encryption.

  • Separate duties: apps handle data, a KMS/HSM handles keys. Never embed keys in code or images.

  • Prefer customer-managed keys for regulated data; keep a clear key hierarchy: root key → key-encryption keys (KEKs) → data-encryption keys (DEKs).

Encryption at Rest

  • Disks and snapshots: enable full-disk encryption on servers, containers, and backups.

  • Databases: use built-in TDE where available; add field-level encryption for high-risk columns.

  • Object storage: enable server-side encryption with KMS (e.g., SSE-KMS) and bucket-level policies.

-- Postgres field-level encryption with pgcrypto (example)
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- Ciphertext + key version stored alongside
ALTER TABLE customers ADD COLUMN ssn_enc bytea, ADD COLUMN key_id text;

-- Encrypt with a per-tenant DEK fetched from KMS and held only in memory
INSERT INTO customers (ssn_enc, key_id)
VALUES (pgp_sym_encrypt(:ssn, :dek, 'cipher-algo=aes256'), :key_id);

-- Decrypt on read (service role only)
SELECT pgp_sym_decrypt(ssn_enc, :dek) AS ssn FROM customers WHERE id = $1;

Encryption in Transit

  • Enforce TLS 1.2+ end to end; prefer TLS 1.3. Disable legacy ciphers.

  • Enable HSTS on public endpoints. Use mTLS for internal service calls when appropriate.

  • Pin public keys or use certificate transparency monitoring for mobile apps.

Use Authenticated Ciphers Correctly

  • Symmetric encryption: AES-256-GCM or XChaCha20-Poly1305.

  • Always use a unique nonce per encryption operation. 96-bit random nonces for GCM are standard.

  • Bind context with AAD so ciphertext cannot be replayed across resources.

// Node example: AES-256-GCM with AAD and unique nonce
import crypto from "crypto";

export function encrypt(plaintext, keyBuf, aadStr) {
  const iv = crypto.randomBytes(12); // unique per operation
  const cipher = crypto.createCipheriv("aes-256-gcm", keyBuf, iv, { authTagLength: 16 });
  const aad = Buffer.from(aadStr, "utf8");
  cipher.setAAD(aad, { plaintextLength: Buffer.byteLength(plaintext, "utf8") });

  const ct = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
  const tag = cipher.getAuthTag();
  // Store iv, tag, key_id, and aad context with the ciphertext
  return { iv: iv.toString("base64"), ct: ct.toString("base64"), tag: tag.toString("base64") };
}

Envelope Encryption with KMS

  • Generate a DEK per tenant or dataset. Encrypt data with the DEK; store the DEK encrypted by a KEK in KMS.

  • Store alongside each record: key_id, encrypted DEK, nonce, tag, and AAD context.

  • Rotate KEKs on a schedule; re-wrap DEKs rather than re-encrypting all data where possible.

# Example (AWS KMS): generate and wrap a DEK
aws kms generate-data-key --key-id alias/pii --key-spec AES_256 \
  --output json > dk.json
# dk.json contains Plaintext (base64 DEK) and CiphertextBlob (wrapped DEK)
# Use Plaintext only in memory to encrypt data; store CiphertextBlob with the record

Key Management and Rotation

  • Store all keys in a managed KMS or HSM. Do not store long-lived keys in environment variables.

  • Enforce least privilege on KMS APIs: separate roles for generate, decrypt, and admin.

  • Rotate KEKs every 6–12 months or on personnel or scope changes. Rotate DEKs more frequently for high-risk data.

  • Track key_id and version everywhere encrypted data is stored. Maintain a re-encryption plan and scripts.

# Example: track versions in secrets manager or vault
vault kv put crypto/prod/pii KEY_VERSION=42 KEK_ALIAS="alias/pii" ROTATED_AT=$(date -Iseconds)

Secrets and Material Handling

  • Use a secrets manager for API tokens, DB creds, and wrapped DEKs. Prefer dynamic, short-lived credentials.

  • Zero logs: never print keys, nonces, or plaintext to logs. Scrub memory after use when libraries support it.

  • Restrict export: disallow secrets in debug endpoints and crash dumps. Block git pushes that contain patterns for keys.

Backups, Snapshots, and DR

  • Encrypt backups with a distinct KEK and store in a separate account or project.

  • Test restore procedures regularly. Verify you can decrypt historical backups after rotations.

  • Keep an offboarding playbook to revoke key use by environment or account if compromised.

Monitoring, Auditing, and Crypto-Shred

  • Log every KMS operation with who, what key, what resource, and decision. Alert on unusual decrypt spikes.

  • Implement crypto-shredding for right-to-erasure: delete or revoke the DEK for a user or tenant to render data unreadable.

  • Keep an append-only audit table for key events tied to data assets.

CREATE TABLE key_audit (
  at timestamptz DEFAULT now(),
  actor text,
  key_id text,
  operation text,     -- generate, encrypt, decrypt, rewrap, revoke
  resource text,
  decision text,      -- allowed, denied
  reason text
);

Quick Encryption and Key Management Checklist

  • Classify data and encrypt at field, record, and volume layers where needed

  • Use AES-256-GCM or XChaCha20-Poly1305 with unique nonces and AAD

  • Keep keys in a managed KMS/HSM; never embed or commit keys

  • Implement envelope encryption with per-tenant or per-dataset DEKs

  • Rotate KEKs and DEKs on a schedule; store key IDs and versions with ciphertext

  • Encrypt backups with separate keys; test restores and decryption paths

  • Log and alert on all key operations; support crypto-shred for erasure

Conclusion

Consistent encryption and disciplined key management turn stolen databases into harmless blobs. By isolating keys in a KMS, using authenticated ciphers with strict nonce rules, rotating and versioning keys, and auditing every decrypt, you reduce breach impact, simplify compliance reviews, and align with GDPR and CPRA expectations for safeguarding personal data.