HostAgentics Docs

HostAgentics Secret Rotation

Last updated: 2026-08-06

This document describes how secrets are protected and rotated on the HostAgentics platform: envelope encryption, the master key ring, per-runtime secrets, the rotation flow, and the rule that plaintext secrets are never logged. It is an internal engineering and operations document; customer-facing behavior (e.g. "keys are shown once, rotated on request") is described in `docs/security.md` and the dashboard help.

1. Envelope encryption (AES-256-GCM)

  • All stored secret material is wrapped in **AES-256-GCM envelopes** (`packages/encryption`): a random per-envelope data key encrypts the secret, and the data key itself is encrypted with a key derived from the master key. Each ciphertext carries a **key version**.
  • Subkeys are derived per context (HKDF-style), so the raw master key is never used directly as a cipher key and one compromised ciphertext cannot be used to derive others.
  • The master key is `ENCRYPTION_MASTER_KEY` (32 random bytes, hex), held only in the control plane's environment. It never appears in logs, error messages, or customer-visible responses.
  • 2. Master key ring and key versions

  • The key ring supports **rotation without re-encrypting everything**: older key versions are retained for decryption while new writes use the newest version. Each envelope records the version that encrypted it.
  • **Key version upgrade**: when a new master key version is introduced, existing envelopes remain readable (old versions retained) and are re-wrapped lazily or in a scheduled batch job so that eventually all envelopes use the current version. A version must never be retired while envelopes still reference it.
  • Master key rotation is a two-person, audited operation (see `docs/security.md` §7).
  • 3. Per-runtime secrets

    Each runtime has its own encrypted secret scope (`encrypted_secrets`, unique per runtime + purpose). Purposes:

    | Purpose | Used by | Notes |

    | ---------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |

    | `gateway-token` | OpenClaw | `OPENCLAW_GATEWAY_TOKEN`; new token on rotation |

    | `db-password` | n8n | Dedicated PostgreSQL password; generated per runtime |

    | `encryption-key` | n8n | `N8N_ENCRYPTION_KEY`; rotating it without re-encrypting stored credentials breaks them — rotation requires an explicit migration plan |

    | `bot-token` | agent channels | Telegram/Discord/Slack/WhatsApp credentials; shown once at submission |

    | `webhook-secret` | Relay/n8n webhooks | Signing secret for callback/webhook payloads |

    | `n8n-api-key` | n8n migration center | API key used to import workflows into the runtime |

    Every envelope stores its key version and a rotation version; rotation increments the rotation version and records `rotatedAt`. The dashboard shows masked hints only.

    4. Rotation flow

    1. **Generate**: the engine generates fresh material (or the customer submits new BYOK material) into the runtime's secret scope as a new envelope. For BYOK, the new key is submitted once and never displayed again.

    2. **Apply**: the adapter re-applies the runtime's environment (`rotateSecrets` → `configure`), so the running service picks up the new value on redeploy.

    3. **Verify**: a health probe confirms the runtime is still healthy with the new credential.

    4. **Retire**: the old value stops working (on redeploy for injected variables; for n8n's `encryption-key`, only with an explicit credential-re-encryption plan).

    5. **Audit**: the rotation is recorded in `auditEvents` (`secrets.rotated`) with actor and correlation ID.

    Platform-level secrets (Stripe keys, the OpenRouter management key, the infrastructure workspace token, `AUTH_SECRET`) are rotated on any suspected exposure; the workspace token and auth secret are rotated on a schedule or incident trigger.

    5. Never log plaintext

  • Log redaction (`packages/observability`) strips known secret patterns at the logging boundary; structured logs carry ciphertext or masked values only, never plaintext secrets.
  • Error messages sent to customers never contain secret material; support diagnostics use correlation IDs and HA-* reference codes.
  • Redaction covers email (Resend), Sentry (deny list includes `ENCRYPTION_MASTER_KEY` and provider tokens), and PostHog (filtered event properties).
  • If a plaintext secret appears in logs, that is a security incident: rotate the affected secret immediately and record a `securityEvents` entry.
  • 6. Related documents

  • `docs/security.md` — key handling and the threat model
  • `docs/ai-credit-system.md` — BYOK key lifecycle
  • `docs/backups.md` — provider-snapshot protection boundary and reserved envelope field
  • `docs/database.md` — encrypted_secrets schema