Security
Security model
What Vaultigen encrypts, where the keys live, who can reveal a secret, and what the design does not protect against.
Vaultigen stores locked boxes in the database, keeps the key to each vault behind a separate installation key, and opens one requested box only after the server confirms that the user is allowed to see it.
The short version
- Secret values are encrypted before storage. The database and attachment store receive ciphertext, not usable passwords.
- Each vault has its own key. Vault keys are wrapped by an installation key kept outside the database.
- Access is checked on every sensitive request. Reveals, downloads, sharing, moves and deletions are authorized on the server.
- The host remains trusted. This is server-side encryption, not zero-knowledge encryption. That boundary is deliberate and documented.
Trust boundary
Designed to protect against:
- a stolen SQL dump or database backup without the installation key,
- stolen attachment storage without its keys,
- accidental exposure through ordinary database tools and replicas,
- users trying to reach vaults they were not granted,
- silent modification of encrypted values (authentication tags detect it),
- accidental overwrite or deletion (revisions and trash).
Not designed to protect against:
- a compromised operating system or PHP process,
- an operator who can deploy modified code or configuration,
- theft of both the data and the encryption keys,
- malware or hostile browser extensions on an authorized user’s device,
- a password a user has already seen, remembered or copied.
The Vaultigen server can decrypt a secret for an authorized user. That is what makes server-side sharing, search, sysPass import, auditing, recovery and TOTP generation practical. A future client-encrypted mode would be a separate product mode, not an invisible switch.
Encryption
Vaultigen uses envelope encryption:
| Layer | Details |
|---|---|
| Installation KEK | Keyring in a protected file (kek.json) outside the database, independent from APP_KEY. |
| Vault key | A random 256-bit key per vault, versioned. The database stores only wrapped copies. |
| Entry documents | Sealed with the vault key using libsodium XChaCha20-Poly1305 with a fresh nonce. |
| Attachments | A random key per file, wrapped by the vault key; content encrypted with libsodium secretstream (XChaCha20-Poly1305). |
Every encrypted value is self-describing (format, algorithm, purpose, key ID, nonce) and bound to the installation, vault, object, purpose and key version. Ciphertext moved to another entry or vault fails validation. Identical passwords produce different ciphertext. Sodium is required; there is no fallback cipher.
What stays readable
A small metadata set stays readable so that the server can search and display lists:
| Readable | Encrypted |
|---|---|
| Entry title | Username and password |
Sanitized host, such as example.com |
Full URL, query string and fragment |
| Vault, folder, client and tag names | Notes and every custom-field value |
| Owner and timestamps | Attachment filename and contents |
| Audit action, actor, target, IP and browser | Secret values, keys, request bodies |
A database dump therefore still reveals your account structure (users, teams, grants, vault names, entry titles, hosts, audit metadata), but not the credentials.
Access control
- Users never receive vault keys. The server decides per request whether to deliver the requested field.
- A user’s access is the highest active grant on the entry, its folder and its vault, directly or through a team.
- Permissions are not cached across requests: deactivation, revocation and expiry take effect on the next request.
- Every reveal writes its audit event before the value is returned. If the audit write fails, the value is not delivered.
- Platform roles, including Super Admin, grant no access to secrets. See Roles and permissions and Emergency access.
Authentication
Invite-only accounts, mandatory multi-factor authentication (authenticator app or email code), short sessions, fresh re-authentication for high-risk actions, and no anonymous web recovery path. Passkey sign-in is planned. See Authentication.
Audit
A hash-chained log with HMAC checkpoints made with a key outside the database. It detects database-only tampering. It is not immutable against someone who controls the host and the audit key. See Audit log.
Plaintext handling
Plaintext secrets exist only briefly in the authorized browser and in application memory. They are not deliberately persisted in queues, sessions, caches, logs, reports or UI state snapshots. Reveal responses are sent with Cache-Control: no-store.
Recovery
Two layers: encrypted revisions and trash for everyday mistakes, and complete encrypted backups with an independent backup key for larger incidents. Losing the installation key makes data unrecoverable; there is deliberately no hidden bypass. See Backups and Key management.
No vendor connection
Vaultigen never contacts its vendor: no telemetry, no activation, no update check. The only optional outbound request is the site icons feature, which fetches a login’s website icon directly from that website and can be turned off in Settings.
Found a mistake? Tell us at [email protected].