# Managed keys (KMS)

Secrets answer "store this value and hand it back later." A **KMS key** answers
a different question: "encrypt, decrypt, or sign *my own data* with a key I never
have to hold." seekrit's KMS is the same zero-knowledge machinery as the rest of
the product — the key material is generated in your client and wrapped to each
principal, so the server only ever stores ciphertext, public keys, and grants.

Unlike a classic server-side KMS (AWS KMS, Vault Transit), seekrit never runs the
crypto for you: a client fetches its wrapped key **once**, unwraps it with its
own private key, and then encrypts, decrypts, and signs entirely locally. The
server cannot read your plaintext, and it cannot use your key.

## What a key is

A managed key is org-scoped and referenced by a stable **name**. It has a
**purpose** that fixes what it does:

- **`encrypt`** — a symmetric AES-256-GCM key, for `Encrypt` / `Decrypt` and
  `GenerateDataKey`.
- **`sign`** — an asymmetric ECDSA P-256 keypair. The private half is wrapped to
  grantees; the public half is **published per version**, so anyone in the org
  can verify a signature without holding the key.

A key may be **scoped** to an application or a group (or left org-wide) — the
same ownership model as environments. Scope organizes keys and drives the
dashboard; a grant is still what actually lets a principal use the key.

## Grants: possession is access

Exactly like an environment DEK, a KMS key reaches a principal only as a
**grant** — the key material wrapped to that principal's public key (a `wd1.`
blob, ephemeral ECDH → HKDF → AES-GCM). Holding a grant row plus the matching
private key *is* the ability to use that key version. Admins grant and revoke;
the crypto is the hard boundary.

## Envelope encryption & GenerateDataKey

`Encrypt` produces a versioned `ce1.` blob. For large payloads, `GenerateDataKey`
returns a fresh random data key **plus** that data key wrapped under the managed
key (a `dk1.` blob): encrypt your bulk data with the plaintext data key, store
the wrapped form beside it, and recover it later with the managed key. This is
the S3-style envelope pattern, done client-side.

## Encryption context (AAD)

`Encrypt` takes an optional **encryption context** — an arbitrary string bound
into the ciphertext as additional authenticated data, mirroring AWS KMS. Decrypt
must supply the same context or it fails. Use it to pin a ciphertext to where it
belongs (`tenant=acme`, `field=ssn`), so a blob can't be silently moved to a
different record. The key id and version are always bound too, so a `ce1.` blob
can never be replayed under a different key or version.

## Versions & rotation

Every key has a **current version** that new operations use. Rotating a key adds
a new version — the client generates fresh material and re-wraps it for every
current grantee — and bumps the current version. **Old versions are retained**,
so ciphertext and signatures produced under them keep decrypting and verifying.
Decrypt reads the version out of the blob and uses the matching material
automatically.

## Signing

A `sign` key produces `sg1.` signatures over any message. Verification only needs
the **published public key** for the signature's version, so a verifier needs org
membership but *not* a grant — sign with a tightly-held key, verify anywhere.

## What the server sees

> **Note:** For an `encrypt` key the server stores the AES key only as `wd1.` grants; for a `sign` key it stores the wrapped PKCS8 private key as grants **and** the public key per version. It never sees the plaintext key material, the values you encrypt, or the messages you sign — those exist only in the client that holds a grant. A full database dump yields ciphertext, public keys, and grant rows.

## When to use a KMS key vs. a secret

Reach for a **secret** to store a config value (a database URL, an API key) that
a process reads at boot. Reach for a **KMS key** when your application does its
own cryptography — encrypting a database column or file, minting an envelope data
key, or signing an artifact or token — and you want the key centrally managed,
grantable, rotatable, and audited without ever exposing it.
