> ## 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.

# Onboard / Configure KMS

> Onboard a customer-managed KMS provider (BYOK) or replace an existing configuration via UPSERT.

## POST /admin/tenant-kms

Onboard a customer KMS provider. KnoxCall performs a live wrap + unwrap round-trip on a 32-byte test payload before committing — if the IAM/RBAC grant isn't working, the request fails immediately and nothing is stored.

Calling this endpoint when a KMS configuration already exists **replaces it** (UPSERT). The probe runs first; if it fails, the existing config is unchanged.

**Auth**: Session JWT (`Authorization: Bearer <session-token>`) **plus** the `X-Tenant-ID` header, and the caller must have the **owner** or **admin** role. Requests missing `X-Tenant-ID` are rejected with `400 X-Tenant-ID header required`. No step-up required.

### Request body

**`provider`** — `aws` | `gcp` | `azure`

**`kms_key_ref`** — The provider-specific key identifier:

* **AWS**: full key ARN (`arn:aws:kms:REGION:ACCOUNT:key/KEY-ID` or `.../alias/ALIAS`)
* **GCP**: full resource path (`projects/P/locations/L/keyRings/R/cryptoKeys/K`)
* **Azure**: vault key URL (`https://VAULT.vault.azure.net/keys/KEY-NAME`)

**`config`** — Provider-specific authentication references. Static long-lived credentials (access keys, service account JSON, client secrets) are rejected at the API level.

| Provider | Required                      | Optional                                                |
| -------- | ----------------------------- | ------------------------------------------------------- |
| `aws`    | `region`, `role_arn`          | `external_id`                                           |
| `gcp`    | `impersonate_service_account` | `project_id`                                            |
| `azure`  | `vault_url`                   | `azure_tenant_id`, `client_id`, `client_secret_env_var` |

<CodeGroup>
  ```bash AWS KMS theme={"dark"}
  curl -X POST https://admin.knoxcall.com/admin/tenant-kms \
    -H "Authorization: Bearer $KC_ADMIN_JWT" \
    -H "X-Tenant-ID: $KC_TENANT_ID" \
    -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": "550e8400-e29b-41d4-a716-446655440000"
      }
    }'
  ```

  ```bash GCP Cloud KMS theme={"dark"}
  curl -X POST https://admin.knoxcall.com/admin/tenant-kms \
    -H "Authorization: Bearer $KC_ADMIN_JWT" \
    -H "X-Tenant-ID: $KC_TENANT_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "gcp",
      "kms_key_ref": "projects/my-project/locations/global/keyRings/knoxcall-keys/cryptoKeys/tenant-master-key",
      "config": {
        "impersonate_service_account": "knoxcall-kms-sa@my-project.iam.gserviceaccount.com",
        "project_id": "my-project"
      }
    }'
  ```

  ```bash Azure Key Vault theme={"dark"}
  curl -X POST https://admin.knoxcall.com/admin/tenant-kms \
    -H "Authorization: Bearer $KC_ADMIN_JWT" \
    -H "X-Tenant-ID: $KC_TENANT_ID" \
    -H "Content-Type: application/json" \
    -d '{
      "provider": "azure",
      "kms_key_ref": "https://my-kv.vault.azure.net/keys/tenant-master-key",
      "config": {
        "vault_url": "https://my-kv.vault.azure.net",
        "azure_tenant_id": "aaaabbbb-cccc-dddd-eeee-ffffgggghhhh",
        "client_id": "11112222-3333-4444-5555-666677778888",
        "client_secret_env_var": "AZURE_KC_CLIENT_SECRET"
      }
    }'
  ```
</CodeGroup>

### Response

```json theme={"dark"}
{
  "ok": true,
  "provider": "aws",
  "kms_key_ref": "arn:aws:kms:us-east-1:111122223333:key/abcd-1234",
  "new_key_version": 1,
  "new_key_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "rewrap_status": "enqueued",
  "note": "A background rewrap pass will re-encrypt existing tenant data under the new key. Existing in-flight agent sessions remain valid for up to 5 minutes (BYOK session TTL)."
}
```

`rewrap_status` is always `"enqueued"` — KnoxCall unconditionally issues a background rewrap lease after onboarding.
