# Customer-controlled recovery

Because seekrit never holds your keys, it cannot reset a passphrase or recover a lost private key
for you — see [protecting user private keys](/docs/concepts/encryption#protecting-user-private-keys).
Left there,
one departed sole key-holder could mean a dead environment. **Customer-controlled recovery** closes
that gap the only way that keeps the [zero-knowledge](/docs/concepts/security) promise intact: you
configure, in advance, a recovery key that a **quorum of custodians you designate** can use to
restore access — and seekrit still holds nothing it could recover on its own.

> **Note:** Recovery restores **environment access to a fresh key-holder** — it does not un-lose a passphrase or a private key. If you forget your own passphrase, your key stays unrecoverable; recovery lets your org grant a *new* principal access to the affected environments instead.

## The recovery key is just another principal

When you enable recovery, a **recovery keypair** is generated in your browser or CLI (P-256, the
same kind every user and token uses). Its **public** half is stored server-side in the clear — a
public key is not a secret. Each environment's data key (DEK) is then *additionally* wrapped to it,
exactly like a [key grant](/docs/concepts/access-control) to any other principal. New environments
are wrapped at creation; `seekrit recovery sync` (or the dashboard) backfills existing ones as
admins who can decrypt them run it.

So the recovery key can unwrap every covered environment's DEK — which is precisely why its
**private** half is never stored whole.

## The private half is split, never held

The recovery private key is split with **Shamir's Secret Sharing** (M-of-N) into one share per
custodian. Each share is wrapped to that custodian's public key before it leaves the browser. The
server stores only:

- the recovery **public** key, and
- **N opaque wrapped shares** it cannot open.

```
                recovery private key
                        │  Shamir M-of-N split
        ┌───────────────┼───────────────┐
        ▼               ▼               ▼
   share 1 →        share 2 →       share 3 →      (each wrapped to one
   custodian A      custodian B     custodian C     custodian's public key)
```

Any **M** custodians can reconstruct the recovery key; any fewer — and seekrit itself, holding only
ciphertext — learn nothing. A single **designated recovery admin** is just the M = N = 1 case.

## The recovery ceremony relays only ciphertext

To exercise recovery, an admin starts a **recovery request** naming a target principal's public key
(usually their own — the person who will end up with access):

1. **Approve.** A quorum of custodians each unwrap their share on their own device and re-wrap it to
   the target's public key. The server collects these re-wrapped shares — all ciphertext it cannot
   read.
2. **Complete.** Once M are collected, the target unwraps them with its own private key, combines
   them back into the recovery key, unwraps each environment's recovery grant to recover the DEK,
   and re-grants itself normal access.

The recovery key exists in plaintext only for the moments of the final step, only on the target's
machine. seekrit never sees a share or the recovery key.

> **Warning:** Recovery is only as strong as your custodian choices. Pick a threshold and a set of people such that no single lost or compromised custodian can either **block** recovery (too high a threshold with too few people) or **perform** it alone (a threshold of 1 with many custodians). After a recovery, consider rotating the recovery key with `seekrit recovery rotate` — the key was briefly reconstructed on one machine.

## What the server never sees

- The recovery **private** key — it is Shamir-split and each share is wrapped to a custodian; the
  server holds only the public key and shares it cannot combine.
- Any **share** in the clear — custodians unwrap and re-wrap on their own devices.
- Any **DEK** in the clear — recovery grants are ciphertext only the reconstructed recovery key can
  open, and that reconstruction happens client-side.

Every step writes an append-only [audit](/docs/guides/audit-export) row (`recovery.configured`,
`recovery.requested`, `recovery.share_contributed`, `recovery.completed`, and so on), so the whole
ceremony is reviewable after the fact. To set it up, see [Set up recovery](/docs/guides/recovery).
