Encryption Architecture
Defence-in-depth: three independent encryption layers
Layer 1 — Encryption at Rest
Amazon Aurora storage is encrypted using AWS KMS with a Customer Managed Key (CMK). The key is rotated annually and access is governed by KMS key policies scoped to the CareSphere IAM role.
- AES-256-GCM via AWS KMS CMK
- Annual automatic key rotation
- S3 backups encrypted with the same CMK
- EBS volumes encrypted at block level
Layer 2 — Column-Level PHI Encryption
Sensitive PHI columns are stored as BYTEA and encrypted individually with pgp_sym_encrypt (pgcrypto). The application PHI key is held in AWS Secrets Manager — never in source code.
- AES-256 symmetric encryption per column
- Key loaded from Secrets Manager at startup
- Decrypted only at query time — never written back
- Minimum-necessary: only required columns decrypted per query
Layer 3 — Encryption in Transit
All network communication — API, database, IoT — is protected by TLS 1.2 or higher. Unencrypted connections are rejected at the database and load-balancer level.
- TLS 1.2+ on all API endpoints (HTTPS)
rds.force_ssl = 1— plaintext DB connections rejected- MQTT over TLS for ESP32 IoT sensors
- HSTS enforced on all web properties
Database Schema Isolation
PHI is physically separated from application data at the schema level
caresphere schema
Non-PHI operational data: facilities, users (login credentials only), roles, sessions, staff profiles, certifications, calendars, inventory, and alerts. Accessible by the application database role.
phi schema
Protected Health Information: resident records, clinical profiles, vitals, ADL scores, mood logs, care notes, incidents, and staff PII. Access is REVOKEd from application roles by default — only role_phi_rw and role_phi_ro can access.
med schema
Medication records including MAR (Medication Administration Records), inventory, and controlled substance waste logs. Separate schema enforces that medication data is never inadvertently exposed by general queries.
audit schema
Immutable event log. Application roles have INSERT only — UPDATE and DELETE are never granted. SIEM tools access via dedicated role_audit_read with SELECT only. No PHI is stored here — only metadata.
REVOKE USAGE ON SCHEMA phi FROM PUBLIC is executed at database creation time. No PostgreSQL role can access PHI tables unless explicitly granted role_phi_rw or role_phi_ro. This is enforced at the database engine level, not just the application layer.18 HIPAA PHI Identifiers Protected
Every identifier defined by 45 CFR §164.514(b) is encrypted in CareSphere
| # | HIPAA Identifier | CareSphere Field(s) | Protection |
|---|---|---|---|
| 1 | Names | phi.residents.first_name, last_name, phi.staff_pii.first_name | BYTEA [ENC] |
| 2 | Geographic data | phi.staff_pii.address, city, zip_postal | BYTEA [ENC] |
| 3 | Dates (except year) | phi.residents.date_of_birth, admission, discharge dates | BYTEA [ENC] |
| 4 | Phone numbers | phi.resident_contact_info.phone, phi.staff_pii | BYTEA [ENC] |
| 5 | Fax numbers | Contact info tables | BYTEA [ENC] |
| 6 | Email addresses | phi.staff_pii.registry_email | BYTEA [ENC] |
| 7 | Social security / SIN numbers | phi.staff_pii.sin_ssn, last_four_ssn | BYTEA [ENC] |
| 8 | Medical record numbers | phi.residents.mrn | BYTEA [ENC] |
| 9 | Health plan beneficiary numbers | Resident health profile | BYTEA [ENC] |
| 10 | Account numbers | Financial records (when applicable) | BYTEA [ENC] |
| 11 | Certificate / license numbers | phi.staff_pii.license_number, ncsbn_id | BYTEA [ENC] |
| 12 | Vehicle / serial numbers | Not applicable to CareSphere | N/A |
| 13 | Device identifiers | IoT device IDs are non-PHI sensor IDs | Non-PHI |
| 14 | Web URLs | Not stored with PHI | N/A |
| 15 | IP addresses | audit.login_events.ip_address — audit only, INET type | AUDIT ONLY |
| 16 | Biometric identifiers | Not collected | N/A |
| 17 | Full-face photographs | phi.residents.photo_s3_key — S3 path is itself encrypted | BYTEA [ENC] |
| 18 | Any other unique identifier | All unique identifiers are reviewed; PHI status applied on discovery | POLICY |
Key Management
Encryption keys never reside in source code or environment files in production
utils/secrets.py. Never logged or included in error responses.