> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Encryption at rest: the platform envelope, and how BYOK fits on top

> How Orbit encrypts tenant data at rest — the platform-managed envelope that is always on, the envelope-encryption design (a data key wrapped by a key-encryption key) that BYOK builds on, the fail-closed seam, and what revoking or rotating a customer key actually guarantees.

# Encryption at rest

Every tenant field Orbit stores is encrypted at rest — that is the platform's
default, not a setting you turn on. On top of that sits a second, separate
layer: a **bring-your-own-key (BYOK) control plane** where you register a key
held in your own KMS and record it as your organization's governing policy.
This page explains the design of both layers — why a data-key/key-encryption
key split is used, what revoking a key guarantees, and why rotation is cheap —
so you can evaluate BYOK for an enterprise or healthcare buyer without reading
source headers. For the register/activate/rotate/revoke workflow itself, see
[Customer-Managed Keys (BYOK)](/compliance/byok-customer-managed-keys).

## 1. Two orthogonal things

Orbit's encryption story has two layers that answer different questions:

* **Platform-managed at-rest encryption** — every tenant's data, always on.
  Secrets, tokens, payload content, and binary compliance documents are
  encrypted before they are stored, under a platform key held in Orbit's
  secret store. Nothing you configure changes this; an organization that
  never touches BYOK is fully covered by it.
* **BYOK — the control plane for your key-management policy** — you register a
  **reference** to a key in your own KMS (AWS KMS, Google Cloud KMS, Azure
  Key Vault, HashiCorp Vault), move it through a lifecycle, and set an
  `enforce` flag that gates how field-encryption calls that consult BYOK
  behave. Orbit stores the reference and a truncated fingerprint — never key
  material.

Keep the two separate in your threat model: platform-managed encryption is
the data-protection layer; your BYOK config is the governance layer that
records which key must govern and fails closed when it cannot.

## 2. The envelope: a data key wrapped by a key-encryption key

Both layers use the same primitive: **envelope encryption** with AES-256-GCM.

1. A fresh random 256-bit **data-encryption key (DEK)** encrypts the payload.
2. The DEK is itself encrypted — **wrapped** — under a **key-encryption key
   (KEK)**.
3. The wrapped DEK is stored beside the ciphertext it protects. The KEK never
   touches Orbit storage.

Splitting the key hierarchy this way buys three properties that a single
master key cannot:

* **Revocation is real.** Destroy the wrapped DEK (or, with a customer KMS,
  disable the KEK) and the ciphertext becomes undecryptable — without
  touching any stored data.
* **Rotation is cheap.** Re-wrapping a DEK is a few hundred bytes of work; the
  bulk ciphertext stays untouched. You rotate a small key, not a dataset.
* **The KEK stays out of storage.** Only the wrapped DEK and a reference to
  the KEK are ever persisted, so a database dump carries no usable key.

Encrypted values carry a versioned prefix — `enc:v1:` for the platform
envelope — so read paths can tell an encrypted blob apart from legacy
plaintext written before encryption was switched on, and a future algorithm
or key-rotation change can bump the version while old rows stay readable.

## 3. The two KEK providers

The KEK in the design above is abstract. Two provider shapes back it:

* **The platform-key provider (default).** The DEK is wrapped under the
  platform key. This needs no extra infrastructure, and because it already
  produces envelope-format ciphertext, a tenant can later move to a customer
  KMS by re-wrapping the small DEK — the bulk ciphertext is never touched.
* **A customer cloud-KMS adapter.** The DEK wrap/unwrap call goes to your KMS
  over the network. Disable or revoke that key and every object sealed under
  it is immediately undecryptable — the guarantee enterprise and healthcare
  RFPs ask for.

In both cases the KEK provider is injected at the call site rather than drawn
from a fixed SDK, so the encryption primitive stays testable and adopting a
specific KMS SDK remains an explicit decision.

## 4. The fail-closed seam

When your BYOK config is `active` and `enforced`, field-encryption calls that
consult BYOK resolve your organization's key material before encrypting or
decrypting. If the key is revoked, never activated, missing its provisioned
wrapped DEK, or its wrapped DEK cannot be recovered, the call fails
**closed** with `409 BYOK_KEY_UNAVAILABLE` — it never silently falls back to
the platform key when your recorded policy says a customer key must govern.

A fail-open fallback would let an operation succeed while violating your
recorded policy. Orbit refuses instead:

```text theme={null}
1. Operation calls a BYOK-consulting field-encryption helper
2. Helper checks the organization's recorded BYOK posture
3. Key is revoked / unprovisioned / unrecoverable
4. Response: 409 BYOK_KEY_UNAVAILABLE — the operation does not proceed
5. Platform key is never silently substituted
```

Fix the key posture (activate an existing key, or register a new one) and
retry the operation.

## 5. Scope: what `enforce` does — and does not do

The `enforce` flag **records your organization's key-management policy and
gates the seam described above.** Read its scope exactly:

* It does **not** re-encrypt existing tenant data. Platform-managed envelope
  encryption stays the layer that actually protects stored data, for enforced
  and non-enforced organizations alike.
* The BYOK seam and key hierarchy are wired and tested today, but the
  product's tenant read/write paths have not yet been moved onto them.
  Until that wiring lands, revoking a key destroys the wrapped DEK it
  provisioned — while rendering no stored tenant data unreadable, because no
  stored field is encrypted under that DEK today.

Do not interpret an active, enforced BYOK config as "tenant data is encrypted
under my key." Today it is a live enforcement seam plus a provisioned key
hierarchy; platform-managed encryption protects the data.

## 6. Lifecycle: register, activate, rotate, revoke

A registered key moves through a state machine:

| From                 | Action                                                | To                               |
| -------------------- | ----------------------------------------------------- | -------------------------------- |
| none / revoked       | `PUT /compliance/byok` (register)                     | `pending`                        |
| `pending`            | `POST /compliance/byok/activate` (optional `enforce`) | `active`                         |
| `pending` / `active` | `POST /compliance/byok/rotate`                        | same state, `rotation_count` + 1 |
| `pending` / `active` | `POST /compliance/byok/revoke`                        | `revoked`                        |

Activation with `enforce: true` is where the key hierarchy is provisioned:
Orbit generates a fresh random per-organization DEK and wraps it under a KEK
derived from your key's fingerprint. From then on the wrapped DEK on record
looks like:

```json theme={null}
{
  "state": "active",
  "enforced": true,
  "fingerprint": "kf_9f2a…",
  "wrappedDek": "mV8ad2…(base64 wrapped DEK)…xQ"
}
```

**Rotate** re-wraps that same DEK under a KEK derived from the new key
reference — a few hundred bytes of work, and no payload ever needs
re-encrypting. If the existing wrapped DEK cannot be recovered during a
rotation, the rotation is refused with `409 BYOK_REWRAP_FAILED` rather than
silently dropping enforcement. **Revoke** clears enforcement and destroys the
wrapped DEK, so it can never be unwrapped again.

### Migrating from the platform provider to a customer KMS

Because even the platform-default envelope keeps its DEK separate from the
KEK, moving a tenant to BYOK is a re-wrap of the small DEK, not a re-encrypt
of the dataset:

1. Register your KMS key reference (`PUT /compliance/byok`) — the config
   enters `pending`.
2. Activate with `enforce: true` — the per-organization DEK is generated and
   wrapped under your key's fingerprint.
3. Rotate later by registering the new reference — the same DEK is re-wrapped
   under the new fingerprint; stored ciphertext is untouched.
4. Revoke to retire — the wrapped DEK is destroyed and the fail-closed seam
   starts refusing BYOK-consulting calls.

## 7. Where to observe and manage it

The same lifecycle is available in the dashboard at
**Settings → Compliance → Customer-Managed Keys**, guarded to organization
owners and admins. Every register, activate, rotate, and revoke writes an
audit-log entry — read it under **Settings → Audit Log**.

* [Customer-Managed Keys (BYOK)](/compliance/byok-customer-managed-keys) —
  the full workflow: provider formats, endpoints, and error codes.
* [Error codes reference](/reference/error-codes) — the
  `BYOK_KEY_UNAVAILABLE` row and every BYOK-specific conflict code.
* [Tenant isolation](/concepts/tenant-isolation) — how tenant data is scoped
  below the encryption layer.
* [HIPAA posture](/compliance/hipaa) — how PHI encryption sits alongside
  your key-management policy.
