Skip to content

Secret storage

Status: Current | Last reviewed: 2026-09-01

TrueServe stores integration and tool credentials separately from non-secret configuration. Regulated deployments use AWS KMS data-key envelopes. Local development and migration can still read the legacy master-key format.

Storage locations

Location Content
integration_secrets One secret field per integration, with encrypted_value, iv, auth_tag, and storage_type.
tool_secrets One secret field per tool, using the same envelope columns.
tenant_settings.knowledge Knowledge API token in api_token_enc.
tenant_settings.telemetry Secret OTLP header values in each header's enc object.
customer-auth settings OIDC client secret envelope.

storage_type = external stores a reference for the configured secret provider. It does not store the referenced value. API reads never return decrypted credentials to the browser.

Managed envelope format

encryptManaged() asks KMS for a fresh AES-256 data key for each value. It encrypts the value with AES-256-GCM, authenticated additional data, and a random 96-bit IV. The data key is immediately zeroed after use. The stored envelope contains the ciphertext, wrapped data key, KMS key ID, format version, and logical context. KMS receives the same context as an encryption context when it unwraps the data key.

The logical context binds a ciphertext to its storage purpose:

Secret Context
Tenant integration or tool integration-secret:{tenant_id}
Platform integration integration-secret:unscoped
Knowledge token tenant:{tenant_id}:knowledge
Telemetry header tenant:{tenant_id}:telemetry:{header_name}
Customer authentication tenant:{tenant_id}:customer-auth

Every runtime supplies the expected context from the owning database row. A tenant requesting access to a platform integration does not become the owner of that secret. In regulated mode, managed-envelope decryption without an explicit expected context fails.

Implementations:

Regulated configuration

Set these values through the dedicated External Secrets reader and workload IRSA roles:

ENVELOPE_KMS_KEY_ARN=arn-for-the-deployment-data-key
AWS_REGION=deployment-region
COMPLIANCE_ENFORCE_ENVELOPE_ENCRYPTION=true
AWS_USE_FIPS_ENDPOINT=true-or-false-for-the-profile

The regulated Helm boundary requires ENVELOPE_KMS_KEY_ARN to equal the data KMS key in the verified deployment manifest. The KMS policy and workload role must permit only the required key and encryption context. FIPS selection configures the AWS SDK endpoint; operators still need evidence for the applicable cryptographic module and boundary.

Migration from the legacy key

The legacy format derives one AES-256-GCM key from MASTER_ENCRYPTION_KEY. It remains readable so an upgrade can migrate without downtime. It is not permitted for new writes when COMPLIANCE_ENFORCE_ENVELOPE_ENCRYPTION=true.

From apps/ai-manager, first inspect without KMS credentials:

pnpm exec tsx scripts/migrate-secrets-to-kms.ts

Then configure the KMS key, region, AWS identity, and legacy master key, and apply:

MIGRATE_SECRETS_APPLY=true pnpm exec tsx scripts/migrate-secrets-to-kms.ts

The migration covers integration secrets, tool secrets, Knowledge settings, telemetry headers, and customer-auth settings. It derives each envelope context from the owning row. Review the count and evidence record, rerun the dry check, deploy readers, and then enable regulated enforcement. Retain the legacy key only through the approved rollback window. Remove it from workloads after every legacy row and backup recovery path has been verified.

KMS key rotation normally changes the backing key material without rewriting every data envelope. A key replacement or boundary change requires a controlled decrypt and re-encrypt migration, access-log review, recovery test, and rollback plan.

Runtime rules

  • Decrypt only at the point of provider use.
  • Never log plaintext, ciphertext envelopes, KMS responses, or external-secret values.
  • Never put secrets in command arguments, files, traces, prompts, model input, audit payloads, or error messages.
  • Use the secret's owning tenant from the database, not a caller-supplied tenant, to construct its context.
  • Treat context mismatch, missing IV or tag, KMS denial, and malformed envelope as a denied operation.
  • Keep service accounts and KMS permissions separate by workload and purpose.

Other sensitive data

API tokens used for verification remain one-way hashes. Database passwords and Redis tokens come from AWS Secrets Manager through External Secrets. Conversation content uses storage-level KMS encryption in the regulated RDS and S3 boundary; it is not field-encrypted by this secret subsystem. Payment card data remains confined to payment-vault memory and the selected payment provider.

See also