BYOK / KMS Encryption

Bring your own AWS KMS key for envelope encryption of provider secrets.

Overview

BrainstormRouter uses envelope encryption for all stored provider keys. Enterprise tenants can bring their own AWS KMS key (BYOK) so that provider secrets are encrypted under a customer-managed CMK. Without BYOK, the platform KMS key (or a local fallback in dev) is used.

Encryption model

  1. Encrypt: KMS GenerateDataKey produces a plaintext DEK and an encrypted

DEK. The plaintext DEK encrypts the secret with AES-256-GCM. Only the encrypted DEK and ciphertext are stored.

  1. Decrypt: KMS Decrypt recovers the plaintext DEK. The DEK decrypts the

ciphertext in memory. Decrypted DEKs are cached in-process (keyed by SHA-256 of the encrypted DEK) to reduce KMS calls.

Cross-account access

When a tenant provides a roleArn, BrainstormRouter uses STS AssumeRole (with optional externalId) to obtain temporary credentials scoped to the customer's AWS account before calling KMS.

Endpoints (JWT auth, mounted at /auth/*)

MethodPathDescription
GET/auth/tenant/kmsRead current KMS config
PUT/auth/tenant/kmsSet KMS ARN and optional role/extId
DELETE/auth/tenant/kmsClear KMS config
POST/auth/tenant/kms/validateTest STS AssumeRole + KMS roundtrip

Configure BYOK

curl -X PUT https://api.brainstormrouter.com/auth/tenant/kms \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "kmsArn": "arn:aws:kms:us-east-1:123456789012:key/abcd-1234",
    "roleArn": "arn:aws:iam::123456789012:role/BrainstormRouterKMS",
    "externalId": "br-tenant-abc"
  }'

roleArn and externalId are optional. If omitted, BrainstormRouter calls KMS directly using its own credentials (only works if the CMK policy grants access).

Validate configuration

curl -X POST https://api.brainstormrouter.com/auth/tenant/kms/validate \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "kmsArn": "arn:aws:kms:us-east-1:123456789012:key/abcd-1234" }'

Performs a full roundtrip: AssumeRole (if roleArn provided) then GenerateDataKey + Decrypt. Returns { ok: true } or an error describing which step failed.

Clearing BYOK

curl -X DELETE https://api.brainstormrouter.com/auth/tenant/kms \
  -H "Authorization: Bearer <jwt>"

Existing provider keys remain decryptable -- each encrypted row stores the KMS ARN it was encrypted with. New keys will use the platform default.

Local development

When KMS_KEY_ARN is not set, a deterministic AES-256 key is derived from the LOCAL_KEK_SECRET environment variable. This exercises the full envelope encryption path without requiring AWS credentials.