274 lines
14 KiB
Markdown
274 lines
14 KiB
Markdown
# 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.
|
|
|
|
## 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.
|