16 KiB
Encryption Boundary and Threat Model
Status
govoplan-encryption is the optional governance and lifecycle boundary for
cryptographic protection. It persists opaque provider references, versioned
content-protection envelopes, idempotent operation state, recovery decisions,
and disable-preflight evidence. It ships a bounded local_aesgcm server-envelope
provider. The provider uses AES-256-GCM, wraps generated vault keys under a key
derived from deployment MASTER_KEY_B64, wraps one generated content key per
envelope, and persists only wrapped keys, nonces, keyed commitments, ciphertext
digests, and opaque references
in shared SQL state. It does not ship a KMS/HSM driver or client E2EE protocol.
Selecting the bundled profile is an authenticated encryption-at-rest claim for the covered payload, not an E2EE, endpoint-security, HSM/KMS, or legal certification claim. Stronger claims require a named protection profile whose provider, clients, algorithms, backup procedure, and failure tests have passed the profile's conformance and security review.
Approved Product Baseline
The product decision recorded on 2026-08-04 separates module activation from content protection. Enabling Encryption makes its capabilities and administration available but never encrypts existing or new content by itself.
- System definitions are reusable profile templates. Tenants explicitly activate profiles for an owner-module collection or individual object. Accounts and groups remain policy subjects rather than cryptographic scopes.
- New objects inherit protection only inside an explicitly activated scope. Existing objects move through an explicit, checkpointed, copy-on-write migration with verified cutover.
- The first production profile is managed server-envelope encryption backed by a KMS/HSM provider. The bundled local provider remains a bounded reference implementation. Tenant-held and client E2EE profiles require separate provider approval and conformance evidence.
- Recovery defaults to a high-assurance, distinct-custodian 2-of-3 quorum with requester separation. Ordinary platform administration does not bypass the ceremony.
- Horizontally scaled nodes may receive only short-lived, in-memory unwrap grants. They do not persist usable key material on node-local storage.
- Disable remains blocked until every protected object is verifiably decrypted, migrated, exported, or destroyed. Externally opaque ciphertext must be resolved through its provider before the owning profile can be removed.
After a migration has retired plaintext, reversal is another governed migration rather than retention of an undisclosed plaintext rollback copy. True E2EE is deliberately not part of the first production profile because it changes search, server-side processing, inspection, reporting, legal-hold export, and recovery guarantees.
Ownership Boundary
Encryption owns:
- vault and opaque provider-key reference metadata;
- key-version and provider-operation lifecycle state;
- versioned protection envelopes and migration evidence;
- high-assurance, quorum-based recovery authorization;
- disable and uninstall preflight.
Feature modules still own domain content, access policy, retention, legal-hold meaning, and normal resource ownership. Identity Trust owns public device keys, key epochs, and recent-assurance evidence. Access decides whether an account may perform a resource action. A positive Access decision does not release a key; an ownership transfer does not transfer cryptographic custody.
No capability in this module accepts or returns plaintext key material.
Administration Surface
Tenant encryption custodians can inspect bounded vault, envelope, migration, recovery, and disable-preflight summaries. These read models deliberately omit provider key references, wrapped-key references, ciphertext locations, and cryptographic material. They are tenant-scoped and bounded to prevent the operator interface from becoming an unrestricted metadata export.
Vault lifecycle actions require optimistic revision, policy-decision, recent assurance, reason, and idempotency evidence. Rotation does not silently migrate old envelopes. Revocation and scheduled destruction explain that prior plaintext cannot be recalled and that content may become unavailable. A migration request only authorizes the operation: the feature module that owns the content must durably apply it and record evidence before success. Provider outcome reconciliation never converts an unknown outcome into success without that evidence.
Recovery requests show quorum, distinct-custodian, expiry, and requester separation requirements. Approval authorizes a later provider-specific action; it does not return keys, change resource ownership, or prove execution.
Assets and Threat Actors
Protected assets include content plaintext, data-encryption keys, wrapping keys, recipient/device private keys, authenticated context, recovery authority, and the integrity and provenance of lifecycle decisions.
The threat model includes:
- an unauthorized user or tenant attempting cross-tenant access;
- a compromised account, API key, worker, or application node;
- a malicious or mistaken tenant/platform administrator;
- a compromised storage service, database backup, queue, log collector, or observability system;
- a lost or revoked device and a former function holder;
- a malicious or unavailable key provider;
- replay, race, partial failure, rollback, and outcome-unknown provider calls;
- ciphertext substitution, context confusion, algorithm downgrade, and mixed migration state;
- backup restoration without matching provider keys, or key restoration without matching metadata.
The initial model does not claim protection against endpoint compromise while a legitimate client has plaintext open, coercion of all configured recovery custodians, traffic analysis, or denial of service by a provider that controls required keys.
Observable Metadata
Unless an independently reviewed profile says otherwise, the server and its database can observe tenant, owner module, resource type and stable id, profile, vault and key version, algorithm suite, ciphertext location and digest, authenticated-context digest, wrapped-key references, timestamps, migration state, policy references, recovery scope, and actor/evidence references.
Titles, recipient identities, content length, access patterns, and relationship graphs may also leak through the owning module or storage provider even when the payload is encrypted. Product UI and documentation must not imply that payload encryption hides this metadata.
Deployment Profiles
Bundled local AES-GCM reference provider
local_aesgcm is a concrete server-side envelope provider intended for bounded
deployments and integration verification. A per-deployment wrapping key is
derived with HKDF-SHA-256 from MASTER_KEY_B64; the master key itself is never
stored in the database. Vault keys and content keys are generated with the
operating-system CSPRNG and wrapped with AES-256-GCM. Every content ciphertext
authenticates a canonical tenant, owner, resource, profile, provider, vault,
key-version, and algorithm context.
The provider stores no unkeyed plaintext digest. Its internal plaintext commitment is keyed by deployment custody and bound to the authenticated resource context, preventing an offline database reader from enumerating low-entropy values such as ballot choices.
The provider supports idempotent provision, rotation, revocation, destruction scheduling, content encryption/decryption, and same-provider key rewrap. A revoked vault key cannot protect new content but can open existing content until destruction. Due destruction clears wrapped vault material and causes reads to fail closed. Payload re-encryption is an explicit two-phase owner-coordinated workflow: Encryption decrypts and prepares an idempotent target ciphertext and exact envelope, while the owner must durably replace its payload before it records the migration as successful. This also permits cross-provider or algorithm migration without giving Encryption ownership of the payload store.
Server-side envelope encryption
The application or a deployment KMS/HSM can unwrap data keys after normal authorization. This protects backups and storage media but not plaintext from a compromised authorized application tier. Provider credentials and key policy are deployment secrets, not envelope metadata. Legal hold can preserve ciphertext and key availability under separately authorized policy.
Tenant-held key provider
The tenant controls an external KMS/HSM or equivalent provider. GovOPlaN holds only references and invokes the provider under tenant policy. The provider may allow server-side processing, but tenant revocation or provider outage can make content unavailable. Backup recovery requires both GovOPlaN state and the tenant's provider recovery procedure.
End-to-end encryption
Only authorized clients possess usable recipient/device private keys; ordinary servers cannot decrypt payloads. Search, preview, server-side Dataflow, virus/content inspection, reporting, legal-hold export, and recovery degrade or become impossible unless the selected profile deliberately adds an authorized recipient or escrow mechanism. Such a mechanism changes the threat model and must be displayed as part of the profile.
The current code can label and track an end_to_end envelope, but it does not
implement the client protocol. That label alone is never evidence of E2EE.
Profile Consequences
| Concern | Server envelope | Tenant-held | End-to-end |
|---|---|---|---|
| Normal server processing | Available after authorization | Provider-policy dependent | Unavailable unless a client performs it |
| Provider outage | Decryption unavailable | Decryption unavailable | Existing enrolled clients may remain usable |
| Platform admin can obtain plaintext | Possible under governed server policy | Tenant/provider dependent | Not from ordinary server custody |
| Legal hold | Preserve ciphertext and governed keys | Requires tenant/provider cooperation | Ciphertext only unless the profile has a hold recipient |
| Export | Governed plaintext or portable encrypted export | Provider cooperation required | Client-produced or recipient-key export |
| Recovery | Provider recovery plus GovOPlaN quorum | Tenant provider recovery plus quorum | Device/recipient recovery defined by the client profile |
| Ownership transfer | Separate reauthorization/rewrap | Separate reauthorization/rewrap | Explicit recipient change and re-encryption |
| Revocation | Stops future provider use; cannot erase prior plaintext | Provider enforced | New key epoch; cannot erase prior client plaintext |
Algorithms, Libraries, and Agility
Concrete providers must declare a versioned suite id and pass conformance tests. The initial allowlist for reviewed profiles is:
- AES-256-GCM through a deployment KMS/HSM or a maintained OpenSSL-backed cryptographic library;
- XChaCha20-Poly1305 through a maintained libsodium implementation where the provider/profile requires extended nonces;
- RFC 9180 HPKE suites for a future reviewed recipient-envelope protocol.
Selection from this list is not automatic approval. A provider profile must also define nonce generation and uniqueness, associated-data construction, key separation, limits, error handling, and test vectors. Home-grown primitives, unauthenticated encryption, AES-ECB, bare AES-CBC, static/reused nonces, raw RSA encryption, SHA-1 integrity, provider-supplied secret values in logs, and silent algorithm fallback are prohibited.
Every envelope fixes its profile, algorithm suite, vault, key version, ciphertext digest, and authenticated-context digest. Changing any of these is a new, evidence-backed migration. Readers never infer an algorithm from current defaults. Old readers fail closed on unknown suites or contract versions.
Durable Operation Semantics
Key-provider operations use a stable idempotency key. GovOPlaN records an
operation as prepared, succeeded, or outcome_unknown. If a provider call
raises or a process dies around the external side effect, absence of an error is
never treated as success. Reconciliation repeats the exact idempotent provider
request and records only bounded error class codes.
An outcome_unknown content migration may subsequently be resolved to success
or rejection; it is not an immutable terminal state.
Content migrations are explicit records. Rewrap and re-encryption succeed only
when an exact target envelope references the authorized source and migration.
Re-encryption preparation leaves the source in migrating and does not register
the active target envelope. Repeating it with the same migration and target
reference returns identical authenticated ciphertext. Only the owner's
evidence-backed outcome call activates the target and retires the source.
Decrypt, export, and destruction require evidence references. Until an outcome
is known, the source remains migration_pending; no implicit plaintext fallback
is allowed.
All runtime state is in the shared database or an external provider/object store reference. Application and worker nodes require no local encryption state, so multiple nodes can retry the same operation safely when the provider honors the idempotency contract.
Recovery Ceremony
Recovery requires current Identity Trust assurance at the high level, a
policy-decision reference, expiry, distinct custodian accounts, and the vault's
configured quorum. The requester cannot approve their own ceremony; one
rejection rejects the current ceremony. Decisions are optimistic-concurrency
protected and replay safe.
An approved ceremony authorizes a later provider-specific recovery action. It
does not return a key, change resource ownership, or prove that recovery has
executed. A production provider must add separately auditable execution and
post-recovery rotation/rewrap evidence.
Disable and Uninstall
Disabling or uninstalling never deletes keys or silently makes ciphertext look like ordinary unreadable content. Preflight inventories all envelopes. It blocks while any envelope is active, pending, migrating, unavailable, or otherwise unresolved. An envelope is locally terminal only after it is:
- migrated to another registered protection envelope;
- decrypted by an authorized workflow;
- explicitly exported with documented custody; or
- cryptographically destroyed with evidence.
A migrated target remains an active protected envelope and therefore still blocks removal of the module/provider that owns it. Destructive table retirement is permitted only after this proof.
Backup, Restore, and Key Loss
A recoverable backup set consists of the shared database, ciphertext/object storage, provider configuration references, provider-side key backups or HSM replication, and audit evidence. These materials must be backed up separately according to their trust boundaries. Database restore without matching provider keys produces an explicit unavailable state; it must never create replacement keys under an old reference.
Before production use, each concrete provider/profile needs automated restore, provider-loss, stale-backup, partial-migration, network-failure, and permanent key-loss exercises. Permanent key loss is data loss for the affected ciphertext and must be reported as such.
Current Integration Contract
Files, Postbox, Campaign, Calendar, and connector credentials may store an envelope id and ciphertext reference while retaining their own resource model. They resolve Encryption through optional capabilities and must fail closed when an encrypted record is encountered without the capability. Unencrypted module combinations continue to operate without Encryption.
Focused fixtures validate Files and Postbox owner adapters: plaintext operation continues without Encryption, configured encrypted writes store ciphertext and an envelope link, encrypted reads fail closed when the capability is absent, and feature modules do not import Encryption models or providers. Files keeps plaintext semantic checksums separate from stored-ciphertext integrity and uses the protection profile in its deduplication identity. Postbox encrypts message bodies while subjects, routing, participant, and attachment-reference metadata remain observable.