Envelope encryption in Skapp
The decision
Skapp encrypts its sensitive data at rest with envelope encryption, using a single application-level data key (DEK) wrapped by a customer-managed key in AWS KMS. One DEK protects the sensitive fields across every tenant: the application unwraps it once at startup, holds it in memory, and uses it for all field-level encryption and decryption. This is the one key for everything model — and for Skapp it is a deliberate choice over per-user and per-tenant keys, not a fallback.
Why a single key is the right fit
Per-user and per-tenant keys solve problems Skapp either doesn't have or already solves another way. A single key is the simplest design that fully meets our obligations — and given our architecture, it gives up nothing that matters.
- Tenant isolation is already handled where it counts. Skapp runs database-per-tenant, so each client's data already lives in its own database. Offboarding a client is a clean database drop — immediate for live data and replicas. The isolation a per-tenant key would add is largely already there at the data layer; the encryption key doesn't need to duplicate it.
- It fully satisfies the security obligation. Field-level encryption of the sensitive columns makes a stolen database dump useless ciphertext — exactly what Article 32 (security of processing) asks for. One key or many, that protection is identical.
- Per-tenant keys couldn't deliver their headline benefit here anyway. The reason to reach for per-tenant keys is instant, backup-inclusive erasure by destroying a key — which depends on having a per-tenant backup to destroy. Skapp's automated backups are whole-instance RDS snapshots, with every tenant in one shared blob under a single instance key. There is nothing per-tenant to shred, so per-tenant keys would add a key table, per-row key resolution, and a migration for a benefit we could never collect (see what crypto-shredding actually erases).
- Individual erasure is a deletion problem, and a solved one. Deleting one employee never needed per-user or per-tenant keys; it is handled by deleting the data and letting backups cycle out — the approach in erasure under a single key.
- Simpler is more reliable. No key table, no per-row key lookups on the hot path, no multi-key migration — fewer moving parts, fewer failure modes. And we keep every envelope-encryption benefit regardless: no plaintext master key at rest, central KEK rotation, and a CloudTrail record of every unwrap.
What we encrypt
Field-level encryption with AES-256-GCM on the special-category columns — examples in general world - national ID, salary, and health data — under the DEK. Ordinary columns such as names, emails, and dates stay as queryable plaintext. That keeps the highest-risk data protected against a dump or backup theft while leaving everything else fully indexable and searchable.
Erasure in practice
Deleting an individual. Hard-delete or anonymize the employee's rows; the change propagates to read replicas immediately. The whole-instance snapshots age out on their retention window, and a small suppression log re-deletes the subject if a snapshot is ever restored.
Offboarding a tenant. Drop the client's database — instant for live data and replicas — then let the shared snapshots age out under the same retention window. The honest, auditable promise to a departing client is then: live data destroyed immediately; the only residue is time-limited system snapshots that are never restored without re-deletion and that expire within the retention window.
The retention window length, and which records carry mandatory retention (example in general - payroll, tax, employment), are compliance and DPO calls, not technical ones. The retention versus erasure section covers the classification approach the implementation honours.
Operational secrets are separate
This decision is about tenant data. Skapp's operational secrets — AWS credentials, inter-service API keys, app-level integration credentials — are platform-owned, not tenant data, so they sit outside this scheme entirely. They belong in the secrets-management layer (AWS Secrets Manager / SSM) under their own app-level KMS key, with separate least-privilege credentials per service and independent rotation. The principle is that key scope follows ownership: this doc decides only how Skapp encrypts tenant data at rest.
The upgrade path
Single key is the right call now, and it doesn't paint us into a corner. If a client contract or a regulator ever requires the most sensitive fields to be destroyed instantly even inside backups, we can introduce per-tenant DEKs for just those columns later, without rearchitecting. The application already resolves the current tenant on every request — it has to, to route to the right database — so selecting a per-tenant key would be the same lookup it already performs. We start simple, and the door to stronger isolation stays open.