Skip to content

What It Protects

Two layers, one human gesture

Muppy Vault uses envelope encryption. The idea fits in a sentence: a key can encrypt another key exactly as it encrypts data.

  • The data keys actually encrypt the secret fields. They live in the database — wrapped (encrypted) in an object called the keyring envelope. That is legitimate: what opens them is elsewhere, and they must be backed up with your data.
  • The master key opens the keyring. It is single, permanent, and written nowhere: it exists in your password manager, and in the memory of a small dedicated process (mpy-masterkeyd) while the instance runs.

The human gesture is deliberately minimal: you only ever type the master key, and you never see a data key. Rotating data keys, re-encrypting records, tracking which key encrypts what — Muppy does all of it behind one screen.

Encryption itself is Fernet — authenticated AES-128-CBC, a proven standard, not homemade cryptography.

Sealed and unsealed

When the master key is present in the key holder, the vault is unsealed: Muppy encrypts and decrypts transparently and everything works as usual.

When it is not — after a machine reboot, typically — the vault is sealed:

  • Reading never breaks the interface. Encrypted fields simply show empty; lists, forms and exports keep working.
  • Using a secret fails loudly. A task that needs an SSH key to act on a host fails as a normal failed job, marked and filterable (see Day-2 Operations).
  • Writing a secret is refused. Muppy will never store a secret in clear "until we can encrypt it".

Unsealing is one screen: enter the master key from your password manager, and Muppy confirms with a count — "Unsealed. N data keys, M readable encrypted values." Sealed is a recoverable, normal state, not an incident.

What it defends — and what it does not

Threat Covered?
Stolen pg_dump, backup, or replica Yes
Read-only database credential, SQL-injection read, curious DBA Yes
Disk snapshot taken under PostgreSQL Yes
Whole-host image or container export Yes — the key lives only in memory, so no filesystem capture holds it
A third party at your unattended screen Yes — via the reveal gate, not the encryption
Root access on the Muppy host itself No — the key must be in memory there for Muppy to run
A Muppy administrator using the interface No — the interface serves secrets by design; that is its job

The last two rows are honest limits, not oversights: encryption at rest defends the copy of your data, never the running instance. What defends the running instance is a second, unrelated control — the gestures that expose a secret re-ask who you are (Revealing Secrets).

What is inside the perimeter

Every field a Muppy model declares as secret: SSH private keys, credentials in the Credentials Vault, API tokens, and more as families are progressively brought in. The Coverage tab of the Encryption screen shows, family by family, how many values are encrypted and how many are still in clear — a number designed to be impossible to overlook rather than a silent gap.

For addon developers

A model brings a field under the vault with a single declaration (inherit the mpy.encrypted_model mixin and point the field at it). That one declaration produces the encryption at rest, the reveal gate and the migration-sweep membership. Partner addons use exactly the same mechanism as Muppy's own models.