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

# KMS Key Management

CyborgDB can persist a per-index **KMS envelope** — a small record describing how an index's KEK is wrapped by an external Key Management Service. AES-256-GCM wraps the 32-byte KEK. These module-level functions read and write that envelope; the envelope itself is represented by the [`KMSBlob`](./types#kmsblob) type and stored alongside the index.

<Note>KMS is an **advanced / optional** feature primarily for the service layer. Embedded SDK users who supply their own KEK can ignore it entirely, or use `provider="none"` (the SDK supplies the plaintext KEK per request and nothing key-derived is stored).</Note>

<Note>
  **Envelope model.** Each index is encrypted with AES-256-GCM under a 32-byte KEK. The KMS envelope records how that KEK is wrapped by an external KMS so a service layer can unwrap it at request time. Supported providers:

  * `"aws"` — the KEK is wrapped with AES-256-GCM under a value stored in AWS Secrets Manager.
  * `"aws-kms"` — the KEK is wrapped via `kms.Encrypt` using an AWS KMS key.
  * `"none"` — no external wrapping; the caller supplies the plaintext KEK per request and nothing is stored.

  Customer-managed keys (CMK) are supported via `"aws-kms"`, not yet for the other providers.

  By default the plaintext KEK lives in caller process memory; the wrapped KEK lives next to the index keystore ([`StorageConfig`](./types#storageconfig)).
</Note>

All functions take a `config_location` ([`StorageConfig`](./types#storageconfig)) identifying where the index keystore lives, plus the index name.

***

## create\_index\_kms

Creates a KMS envelope for an index. **Strict insert** — fails if an envelope already exists for `index_name`.

```python theme={null}
def create_index_kms(config_location: StorageConfig,
                     index_name: str,
                     blob: KMSBlob)
```

### Parameters

| Parameter | Type | Description |
| - | - | - |
| `config_location` | [`StorageConfig`](./types#storageconfig) | Backing store where the index keystore lives. |
| `index_name` | `str` | Name of the index the envelope belongs to. |
| `blob` | [`KMSBlob`](./types#kmsblob) | The KMS envelope to store. |

### Example Usage

```python theme={null}
import cyborgdb_core as cyborgdb

config = cyborgdb.StorageConfig.disk("/tmp/cyborgdb")

blob = cyborgdb.KMSBlob(
    kms_name="prod-kms",
    provider="aws-kms",
    key_id="arn:aws:kms:us-east-1:123456789012:key/abcd-...",
    region="us-east-1",
    wrapped_kek=b"...",  # KEK wrapped by the external KMS
    version=1,
)

cyborgdb.create_index_kms(config, "my_index", blob)
```

***

## push\_index\_kms

Stores a KMS envelope for an index. **Idempotent upsert** — creates the envelope if missing, otherwise overwrites it.

```python theme={null}
def push_index_kms(config_location: StorageConfig,
                   index_name: str,
                   blob: KMSBlob)
```

### Parameters

| Parameter | Type | Description |
| - | - | - |
| `config_location` | [`StorageConfig`](./types#storageconfig) | Backing store where the index keystore lives. |
| `index_name` | `str` | Name of the index the envelope belongs to. |
| `blob` | [`KMSBlob`](./types#kmsblob) | The KMS envelope to store (replaces any existing one). |

### Example Usage

```python theme={null}
# Rotate the wrapped KEK without caring whether an envelope already exists
blob.wrapped_kek = b"...new wrapped kek..."
blob.version = 2
cyborgdb.push_index_kms(config, "my_index", blob)
```

***

## get\_index\_kms

Retrieves the KMS envelope for an index.

```python theme={null}
def get_index_kms(config_location: StorageConfig,
                 index_name: str) -> KMSBlob
```

### Parameters

| Parameter | Type | Description |
| - | - | - |
| `config_location` | [`StorageConfig`](./types#storageconfig) | Backing store where the index keystore lives. |
| `index_name` | `str` | Name of the index the envelope belongs to. |

### Returns

[`KMSBlob`](./types#kmsblob): The stored KMS envelope for the index.

### Example Usage

```python theme={null}
blob = cyborgdb.get_index_kms(config, "my_index")
print(blob.provider, blob.key_id, blob.version)
```

***

## delete\_index\_kms

Deletes the KMS envelope for an index. **Idempotent** — deleting a non-existent envelope is a no-op.

```python theme={null}
def delete_index_kms(config_location: StorageConfig,
                    index_name: str)
```

### Parameters

| Parameter | Type | Description |
| - | - | - |
| `config_location` | [`StorageConfig`](./types#storageconfig) | Backing store where the index keystore lives. |
| `index_name` | `str` | Name of the index the envelope belongs to. |

### Example Usage

```python theme={null}
cyborgdb.delete_index_kms(config, "my_index")
```

***

## Rotation

To rotate the wrapped KEK, re-wrap it with your external KMS and store the new envelope with [`push_index_kms`](#push_index_kms) (an idempotent upsert), bumping `version`:

```python theme={null}
blob = cyborgdb.get_index_kms(config, "my_index")
blob.wrapped_kek = b"...newly wrapped kek..."
blob.version += 1
cyborgdb.push_index_kms(config, "my_index", blob)
```

For end-to-end key-rotation guidance, see the [CyborgDB documentation](https://docs.cyborg.co).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.