Security model
Secronna is built so that a secret's plaintext exists in as few places, for as short a time, as possible — and so that every time a value is read back, there's a record of it.
Envelope encryption
Values are never stored with a single key. Secronna uses a layered (envelope) key hierarchy:
- Master key — the root key, held outside the application database. It only ever wraps other keys; it never touches a secret value directly.
- Project KEK (key-encryption key) — each project gets its own KEK, stored encrypted (wrapped) by the master key. This scopes a compromise: unwrapping one project's secrets requires that project's KEK.
- Per-version data key — every secret version gets its own fresh data key, stored wrapped by the project KEK.
- Value — the secret value is encrypted with its version's data key using AES-256-GCM (authenticated encryption, so tampering is detected on decrypt).
To reveal a value, Secronna unwraps the chain top-down: master key → project KEK → per-version data key → decrypt the value. Rotating the master key re-wraps only the KEKs, not every value; rotating a project KEK re-wraps only that project's data keys.
Immutable, versioned secrets
Writing a key never overwrites the previous value. Each PUT mints a new
immutable version with its own data key, and the key's
currentVersion pointer advances. Old versions remain decryptable (via
their own data keys) until the secret is deleted, which is what makes
reveal?version=<n> and point-in-time recovery possible. Because each
version is encrypted under a distinct data key, a leaked data key exposes
exactly one version of one secret.
Audited reveals
Listing secrets returns keys only — never values. The only way to
read a plaintext value is the explicit POST /secrets/:id/reveal
endpoint, and every reveal writes an audit-log entry recording who
revealed which secret, which version, and when. Writes, deletes, and
project/environment creation are audited too. Query the trail with
GET /audit?limit=<n>. Convenience helpers like the SDKs' fetchSecrets
and the CLI's secronna run reveal each key individually, so they
produce one secret.reveal entry per key — bulk access is still fully
attributable.
Private-beta allowlist
Secronna is in private beta. Beyond Huudis authentication, a workspace must be on the Secronna allowlist for its API keys and tokens to work; requests from a workspace that isn't allowlisted are rejected. This keeps the surface small while the product hardens.
What this means for you
- Least exposure: a value's plaintext only materializes during a reveal, and only that one version's key can decrypt it.
- Full attribution: every read is on the record — there is no silent path to a secret value.
- Recoverability: immutable versions let you read or roll back to a prior value without losing history.