Skip to content

Secrets posture

How CDC stores and hands out the secrets it needs (plugin credentials, connection strings, API keys), and why the design resists exfiltration. Written for an evaluator assessing the secret-handling stance; see the security posture for the wider picture.

The defining property of CDC’s secret store is that no API path returns a stored secret value. An operator with full administrative access can set a secret and overwrite it, but cannot read it back. The management surface exposes only:

  • list the keys that exist,
  • write (or overwrite) a value,
  • delete a value.

There is deliberately no “get value” endpoint. The consequence for a threat model is direct: compromising an authenticated operator session does not yield the secret material. A secret can be rotated by whoever holds the write scope, but it cannot be exfiltrated through the API by anyone. Consumers that legitimately need a secret (a plugin instance connecting to a source system) receive it in-process through the platform’s secret-provider abstraction, never over an API round-trip that a caller could observe.

This is a materially stronger stance than a store that lets an admin view a secret “to check it,” which turns every admin session into a potential exfiltration path.

Pluggable backends: local or external vault

Section titled “Pluggable backends: local or external vault”

The secret store is a provider abstraction with two backends an operator chooses per deployment:

  • External managed vault (e.g. Azure Key Vault): the natural choice for cloud deployments, delegating storage and key management to the managed service.
  • Local encrypted store: for development and for on-premise deployments that cannot or will not depend on an external vault, values are held as AES-256-GCM authenticated-encryption ciphertext, with a fresh nonce per write and the authentication tag stored alongside.

The write-only API contract is identical across backends, so the security posture an evaluator assesses does not change with the storage choice, only where the bytes live.

The local encrypted backend is protected by a single 32-byte master key, supplied to the host through the environment (not committed to configuration) and read once at startup. An evaluator should understand its properties:

  • It is the root of trust for local secrets. Every stored value is encrypted under it.
  • There is no recovery path if it is lost or changed. Losing or rotating the master key invalidates every existing ciphertext: the stored secrets become unrecoverable and must be re-entered. This is a deliberate consequence of the master key being the only thing that decrypts them; it must be backed up through the same channel as other production secrets and treated as a break-glass artefact.
  • It never touches the database. The key lives only in the host’s environment and memory; the store holds ciphertext and nonces, so a database compromise alone does not reveal secrets.

Deployments that would rather not own master-key lifecycle at all choose the external managed vault, where the cloud provider’s key management applies instead.

Where a secret protects a live operation (for example the credential CDC uses to administer identities write-through), it is resolved from the vault at the moment of use, not cached from startup configuration. Rotating that secret in the vault therefore takes effect immediately, without redeploying or restarting the host. This keeps rotation an operational action rather than a deployment event.

  • Secrets are write-only through the API (settable and rotatable, never readable), so an operator compromise does not surrender secret material.
  • Backends are pluggable (external managed vault or local AES-256-GCM store) with an identical write-only contract.
  • The local store’s master key is an environment-supplied root of trust with no recovery path: a clear, auditable backup and break-glass obligation.
  • Live-use secrets are resolved at call time, so rotation is immediate.