Defense in depth. Denialbase encrypts data at the disk, bucket, row, column, and wire levels — with customer-managed keys wherever GCP supports them.
At rest
Cloud SQL (PostgreSQL)
AES-256 with customer-managed encryption keys (CMEK) in Google Cloud KMS. 90-day automatic key rotation. Keys live in a dedicated KMS key ring per environment.
Cloud Storage (documents)
EOBs, denial letters, appeal letters, and medical records are stored in CMEK-encrypted GCS buckets with
uniform_bucket_level_access and public_access_prevention = enforced.Memorystore Redis
Session caches, rate-limit counters, and 2FA tokens use CMEK-encrypted Memorystore. Connection is TLS (
rediss://) over private VPC.Terraform state
Our infrastructure state bucket uses a separate CMEK key with access restricted to CI/CD via Workload Identity Federation — no static keys.
In transit
- External traffic: TLS 1.2+ only. Enforced at the Google Cloud load balancer. HSTS preload.
- Internal traffic: GCP services communicate over Google’s private backbone; cross-region traffic is encrypted in transit.
- Database connections: Cloud SQL connections are TLS-encrypted; app-to-DB goes over a private VPC peering link.
- Redis connections:
rediss://TLS endpoint with private IP only.
Column-level PHI encryption
On top of the disk-level CMEK encryption, specific PHI columns are encrypted with Active Record Encryption before being written to the database. This means even a direct SQL query against the table returns ciphertext.What’s encrypted today
| Model | Encrypted columns | Deterministic? |
|---|---|---|
User | first_name, last_name | Deterministic (queryable) |
User | phone_number, address_line1, address_line2, date_of_birth | Non-deterministic |
InsuranceMember | name, phone_number, email, address_line1, date_of_birth | Mix |
InsuranceProfile | member_id, group_number | Deterministic |
InsuranceProfile | policy_number, insurer_phone, appeals_phone, insurer_fax, claims_address, patient_address | Non-deterministic |
OverturnableDenial | diagnosis_codes (JSON), patient_name, patient_dob | Non-deterministic |
Migration status
Key management
- Encryption keys live in GCP Secret Manager, not in source code or environment files.
- Three keys per environment: primary encryption key, deterministic encryption key, key-derivation salt.
- Access to keys is granted via IAM bindings only to the application’s runtime service account.
- Access to Secret Manager is audit-logged by Google’s Cloud Audit Logs.
Key rotation
| Key | Rotation cadence |
|---|---|
| CMEK (Cloud SQL, GCS, Redis) | Automatic, every 90 days |
| Terraform state CMEK | Automatic, every 90 days |
| Active Record encryption keys | Manual — rotation requires re-encryption of all data. Procedure documented in our internal secret-rotation runbook. |
| JWT signing key | Manual — dual-secret validation for zero-downtime rotation is in progress (target Q2 2026). |