---
title: "Key Management"
canonical: "https://helm.docs.mindburn.org/security/key-management"
source: "helm-ai-enterprise/docs/public/security-and-trust/key-management.md"
edit: "https://github.com/Mindburn-Labs/helm-ai-enterprise/edit/main/docs/public/security-and-trust/key-management.md"
section: "trust"
access: "public"
sensitivity: "public"
last_reviewed: "2026-04-30"
checksum_sha256: "sha256:e9746bfeaca8de774fb6b38ad01a9489a66f33cb3dded68da3e02b9f6d564193"
build_timestamp: "2026-05-24T13:40:27.882Z"
---
# Key Management

## Audience

## Outcome

After this page you should know what this surface is for, which source files own the behavior, which public route or adjacent page to use next, and which validation command to run before changing the claim.

## Source Truth

- Public route: `security/key-management`
- Source document: `helm-ai-enterprise/docs/public/security-and-trust/key-management.md`
- Public manifest: `helm-ai-enterprise/docs/public-docs.manifest.json`
- Source inventory: `helm-ai-enterprise/docs/source-inventory.manifest.json`
- Validation: `corepack pnpm run docs:coverage`, `corepack pnpm run docs:truth`, and `npm run coverage:inventory` from `docs-platform`

Do not expand this page with unsupported product, SDK, deployment, compliance, or integration claims unless the inventory manifest points to code, schemas, tests, examples, or an owner doc that proves the claim.

## Troubleshooting

| Symptom | First check |
| --- | --- |
| A link or route is missing from the docs website | Check `docs/public-docs.manifest.json`, `llms.txt`, search, and the per-page Markdown export before changing navigation. |
| A claim is not backed by code or tests | Remove the claim or add the missing code, example, schema, or validation command before publishing. |

HELM uses layered credential protection with AES-256-GCM at-rest encryption and strict access controls.

## Current Architecture

| Layer | Mechanism |
|-------|-----------|
| At-rest encryption | AES-256-GCM with 256-bit derived key |
| Key derivation | PBKDF2-HMAC-SHA256, 600 000 iterations |
| Memory | Credentials zeroed after use via `memguard` |
| Access | Environment variable `HELM_CREDENTIAL_KEY` (bootstrap) |
| Rotation | `RotationManager` with configurable TTL and grace period |

## Key Storage

The credential encryption key is currently stored as an environment variable (`HELM_CREDENTIAL_KEY`). For production deployments, operators **SHOULD** use an external KMS:

### HSM / KMS Integration Path

| Provider | Integration | Status |
|----------|-------------|--------|
| AWS KMS | `aws-sdk-go-v2/service/kms` — use `GenerateDataKey` for envelope encryption | Planned |
| GCP Cloud KMS | `cloud.google.com/go/kms` — use `Encrypt`/`Decrypt` with symmetric keys | Planned |
| Azure Key Vault | `azkeys` SDK — use `WrapKey`/`UnwrapKey` for key wrapping | Planned |
| HashiCorp Vault | Transit secrets engine — use `encrypt`/`decrypt` endpoints | Planned |
| PKCS#11 HSM | `miekg/pkcs11` — direct HSM integration for hardware-backed keys | Planned |

**Envelope encryption pattern**: KMS encrypts a Data Encryption Key (DEK); the DEK encrypts credentials locally. Only the encrypted DEK is stored alongside the ciphertext.

## Key Rotation

The `RotationManager` (in `core/pkg/credentials/rotation.go`) supports:

1. **Automatic rotation** — configurable TTL (default: 90 days)
2. **Grace period** — old key remains valid for decryption during transition (default: 24 hours)
3. **Re-encryption** — all credentials are re-encrypted with the new key during rotation
4. **Audit trail** — rotation events are logged to the Guardian audit log

### Rotation Procedure

```bash
# 1. Generate new key
export HELM_CREDENTIAL_KEY_NEW=$(openssl rand -hex 32)

# 2. Trigger rotation (re-encrypts all stored credentials)
helm credentials rotate --new-key-env HELM_CREDENTIAL_KEY_NEW

# 3. Update environment
export HELM_CREDENTIAL_KEY=$HELM_CREDENTIAL_KEY_NEW
unset HELM_CREDENTIAL_KEY_NEW
```

## Recommendations

> [!IMPORTANT]
> For production deployments handling sensitive data, use an external KMS rather than environment variables for the master encryption key.

- **Development**: Environment variable is acceptable
- **Staging**: Use cloud KMS with IAM-scoped access
- **Production**: Use cloud KMS or HSM with audit logging and automatic rotation

## Diagram

```mermaid
flowchart TD
    subgraph Ingestion["1. Ingestion & Context Plane"]
        source["Key Management"]
        s0["Current Architecture"]
        s1["Key Storage"]
        s2["Key Rotation"]
        s3["Recommendations"]
        output["Reader outcome"]
    end

    %% Operational Flow Edges
    source --> s0
    s0 --> s1
    s1 --> s2
    s2 --> s3
    s3 --> output

    %% Premium Styling Rules
```
