> For the complete documentation index, see [llms.txt](https://docs.envector.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.envector.io/1.5.x/key-management/managed-kms/kms.md).

# KMS Operations

Operational runbook for the enVector KMS. For the design and key hierarchy see [KMS Architecture](/1.5.x/key-management/key-management.md); for KEK rotation and incident response see [Key Rotation & Incident Response](/1.5.x/key-management/managed-kms/key-rotation.md).

## Architecture at a glance

The KMS exposes a gRPC/HTTP API gateway that fronts a public-key store and, behind a TEE trusted boundary, the KeyManager and TopK services plus the Secret Manager (Vault/OpenBao). The control plane never holds Vault tokens or raw key material — only the KMS-TEE does.

| Component                      | Role                                           | Default host port |
| ------------------------------ | ---------------------------------------------- | ----------------- |
| KMS API Gateway (gRPC)         | Key generation/distribution, managed-key flows | `50090`           |
| KMS API Gateway (HTTP)         | Admin/secret-manager REST API                  | `50091`           |
| Public Key Storage             | Object storage for public/eval key files       | —                 |
| Secret Manager (Vault/OpenBao) | Secret-key store (sealed keys and secrets)     | — (internal only) |

> The KMS API is exposed over **TLS (https) by default**. The examples below verify the root CA with `--cacert "${KMS_HTTP_CACERT}"`. For a non-TLS (`notls`) deployment, set `KMS_HTTP_SCHEME=http` and omit `--cacert`.

## Session variables

Set these once at the start of an operational session (see also [Authentication](/1.5.x/operations-and-management/authentication.md) for token issuance):

```bash
export KMS_HTTP_SCHEME="${KMS_HTTP_SCHEME:-https}"
export KMS_HTTP_PORT="${KMS_HTTP_PORT:-50091}"
export KMS_HTTP_ADDR="${KMS_HTTP_SCHEME}://127.0.0.1:${KMS_HTTP_PORT}"
export KMS_HTTP_CACERT="${KMS_HTTP_CACERT:-$(pwd)/kms-volumes/envector-ca-certs/root_ca.crt}"
```

If the `KMS_HTTP_CACERT` path does not exist, extract it from the CA container:

```bash
docker compose -p ${COMPOSE_PROJECT_NAME} cp step-ca:/certs/ca/root_ca.crt /tmp/root_ca.crt
export KMS_HTTP_CACERT=/tmp/root_ca.crt
```

## 1. Status check

```bash
curl -fsS --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/admin/secretmgr/status" \
  | jq -e '.initialized == true and .sealed == false and .runtime_token_ready == true'

curl -fsS --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/health" \
  | jq -e '.status == "healthy"'
```

| Field                 | Expected | Meaning                                     |
| --------------------- | -------- | ------------------------------------------- |
| `initialized`         | `true`   | Initial init completed                      |
| `sealed`              | `false`  | Unseal completed; normal operation possible |
| `runtime_token_ready` | `true`   | Runtime token issuance completed            |

## 2. Unseal (required on every restart)

The KMS enters the **sealed** state on container restart, and the `runtime_token` must be prepared again. After any restart you must re-run the unseal procedure with the shares.

```bash
# Use the script (recommended — handles the TLS CA automatically)
./scripts/kms/init_secretmgr.sh --port "${KMS_HTTP_PORT}"

# Or curl directly
curl -sS -X POST --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/admin/secretmgr/bootstrap" \
  -H 'Content-Type: application/json' \
  -d '{"shares":["<share-1>"]}' | jq
```

> The shares (SSS) issued during the init step are **unrecoverable once lost**. Manage them per your organization's secret-management policy (distributed storage, HSM, etc.). See [Key Rotation & Incident Response](/1.5.x/key-management/managed-kms/key-rotation.md).

## 3. Key generation and lookup

Key generation is asynchronous: a new key starts `PENDING` and transitions to `KEY_GEN_STATUS_READY`.

```bash
export KMS_KEY_ID="ops-$(date +%s)"

curl -fsS -X POST --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/keys/generate" \
  -H 'Content-Type: application/json' \
  -d "{\"key_id\":\"${KMS_KEY_ID}\"}" | jq .

until curl -fsS --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/keys/${KMS_KEY_ID}/status" \
  | jq -e '.status == "KEY_GEN_STATUS_READY"' >/dev/null; do
  sleep 2
done

curl -fsS --cacert "${KMS_HTTP_CACERT}" "${KMS_HTTP_ADDR}/api/keys" | jq .
```

## 4. Operational considerations

* Key generation is asynchronous: `PENDING` immediately after creation → `KEY_GEN_STATUS_READY` after a short time.
* When called in the `sealed` state, the API returns an error with `runtime_token_ready: false`. Unseal immediately.
* **Include the Secret Manager (Vault/OpenBao) data volume mounted in the KMS container in your backup policy.** If it is lost, unsealing is impossible.
* The homomorphic-encryption SecKey is **not stored on the server**. If the client loses it, both score decryption and search over existing data become impossible — back it up to an external secure medium immediately after key generation.

## Key environment variables

| Variable                         | Default         | Description                                               |
| -------------------------------- | --------------- | --------------------------------------------------------- |
| `ENVECTOR_KMS_GRPC_HOST_PORT`    | `50090`         | KMS gRPC host-exposed port                                |
| `ENVECTOR_KMS_HTTP_HOST_PORT`    | `50091`         | KMS HTTP/API host-exposed port                            |
| `ENVECTOR_KMS_SEAL_MODE`         | `vault-transit` | Seal/unseal operating mode (e.g. `vault-transit`, `none`) |
| `ENVECTOR_KMS_DECRYPT_TOPK_JOBS` | `1`             | Top-k decryption job concurrency                          |

See [Server System Config](/1.5.x/operations-and-management/server-environment.md) for the full environment-variable reference.

## Troubleshooting

| Symptom                                             | Action                                                                                             |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| KMS in `sealed` state                               | Re-run [Unseal](#2-unseal-required-on-every-restart)                                               |
| `runtime_token_ready=false`                         | Unseal not performed, or Vault data corrupted → unseal or restore the Vault data volume            |
| `KeyManagementError: GenerateKey failed` (SDK side) | KMS sealed, or insufficient disk/permissions → unseal, check `df -h` and key directory permissions |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.envector.io/1.5.x/key-management/managed-kms/kms.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
