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

# Tenant KMS (BYOK) overview

> Bring your own KMS key from AWS, GCP, or Azure. KnoxCall wraps all tenant data under your key — you hold the kill switch.

# Tenant KMS (BYOK) Overview

By default every KnoxCall tenant's master key is wrapped by the platform's own `MASTER_KEY_B64`. That's strong isolation, but the wrapping key lives on KnoxCall's infrastructure.

**Tenant KMS** lets you go a step further: the wrapping key lives in **your** cloud account. KnoxCall is granted a narrow IAM permission to call `Encrypt` / `Decrypt` against that one key — nothing else. Revoke the grant and KnoxCall can no longer unwrap on the next cache miss. The tenant enters the [sealed state](/essentials/tenant-kms/sealed-state) on that next miss — up to one hour later, since the unwrapped master key is cached for one hour.

## How it differs from Operator KMS

There are three wrapping options:

| Wrap method               | Who holds the wrapping key         | Kill-switch location   |
| ------------------------- | ---------------------------------- | ---------------------- |
| `global`                  | KnoxCall (env var)                 | None — contact support |
| `operator_kms`            | KnoxCall-managed KMS key           | None — contact support |
| `customer_kms` (**BYOK**) | **Your** AWS / GCP / Azure account | **Your** IAM console   |

BYOK is Customer KMS. The Tenant KMS dashboard manages it.

## When to use it

* **Regulatory requirement** — FedRAMP, HIPAA, HITRUST, EU data residency frameworks that require customer-controlled key material
* **Kill-switch requirement** — need to instantly revoke KnoxCall's access to tenant data without contacting support
* **Audit requirement** — need your own KMS audit log to record every unwrap call KnoxCall makes

<Warning>
  BYOK tenants have a **5-minute agent session window**, not the standard 1 hour. Agent sessions renew more frequently so that a revoked KMS grant caps in-flight plaintext exposure at roughly 5 minutes. Plan for this if you run long-lived self-hosted proxy deployments. (This is the agent *session* TTL — the in-process master-key cache TTL is 1 hour for all tenants.)
</Warning>

## Architecture

KMS is not in the path of every encrypt/decrypt — only on a cache miss:

```text theme={"dark"}
Incoming request
    ↓
KnoxCall proxy needs tenant master key
    ↓
Cache HIT → use cached key (valid for 1 hour)
Cache MISS → call customer KMS via IAM → unwrap master key → cache for 1 hour
    ↓
Encrypt / decrypt with master key (local, fast)
```

This means one KMS round-trip per 1-hour window, not per request.

### Key version states

| State     | Meaning                                                                        |
| --------- | ------------------------------------------------------------------------------ |
| `active`  | Current version. New wraps use this. One per tenant at a time.                 |
| `retired` | Older version — still unwraps legacy ciphertext, no new wraps.                 |
| `revoked` | Cryptographic erasure. Data wrapped by this version is permanently unreadable. |

## Prerequisites

* **Owner** or **Admin** role on the tenant
* Provider IAM set up before onboarding — KnoxCall validates the grant at onboarding time

<Info>
  Static long-lived credentials (AWS access keys, GCP service account JSON key files) are **rejected at the API level**. AWS uses cross-account STS role assumption; GCP uses service account impersonation; Azure uses a client secret env var or Managed Identity. No credential value is ever stored in the database.
</Info>

<Note>
  Onboarding (`POST /admin/tenant-kms`) does **not** require a step-up verification. Step-up is only required for sensitive post-onboard operations: unseal (2-minute window) and rotate (5-minute window).
</Note>

## Quick start

Before saving, KnoxCall runs a **probe**: wrap then unwrap 32 test bytes against your KMS key. If the IAM grant isn't working, the request fails immediately and nothing is written to the database. Calling this endpoint when a KMS config already exists **replaces it** (UPSERT) — the probe runs first; if it fails, the existing config is unchanged.

```bash theme={"dark"}
curl -X POST https://admin.knoxcall.com/admin/tenant-kms \
  -H "Authorization: Bearer $KC_ADMIN_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "aws",
    "kms_key_ref": "arn:aws:kms:us-east-1:111122223333:key/abcd-1234-...",
    "config": {
      "region": "us-east-1",
      "role_arn": "arn:aws:iam::111122223333:role/KnoxCallKMSAccess",
      "external_id": "your-chosen-external-id"
    }
  }'
```

For the full setup flow for each provider, see the pages below.

## Cache architecture

The master key is cached **in-process on the KnoxCall control plane** — not per-agent and not in Redis. Cache key: `<tenant_id>:active`, TTL 1 hour (`DEFAULT_CACHE_TTL_MS`) for all tenants. Concurrent cache misses for the same tenant are deduplicated: a single KMS call is made and the result is shared to all waiters. This means KnoxCall makes roughly one KMS call per 1-hour window per tenant, regardless of agent count.

## Sealed state

If KnoxCall can't reach your KMS (IAM revoked, network partition, key disabled), the tenant enters the **sealed state**. New agent sessions fail with `503 Service Unavailable`. In-flight agents with a valid session continue operating until their session expires (at most 5 minutes for BYOK tenants). See [Sealed state and unseal](/essentials/tenant-kms/sealed-state) for recovery steps.

<CardGroup cols={2}>
  <Card title="AWS KMS setup" icon="aws" href="/essentials/tenant-kms/setup-aws">
    Cross-account IAM role + STS assumption
  </Card>

  <Card title="GCP Cloud KMS setup" icon="google" href="/essentials/tenant-kms/setup-gcp">
    Service account impersonation — no JSON key files
  </Card>

  <Card title="Azure Key Vault setup" icon="microsoft" href="/essentials/tenant-kms/setup-azure">
    Managed Identity or Federated Credentials
  </Card>

  <Card title="Sealed state and unseal" icon="lock-open" href="/essentials/tenant-kms/sealed-state">
    What happens when KMS is unreachable, and how to recover
  </Card>

  <Card title="Key rotation" icon="refresh-cw" href="/essentials/tenant-kms/key-rotation">
    Rotate your tenant master key under a new KMS-backed version
  </Card>

  <Card title="Key Management concepts" icon="key-round" href="/essentials/key-management/byok-and-kms">
    Background on global / operator\_kms / customer\_kms wrapping options
  </Card>
</CardGroup>
