A database client stores passwords, SSH passphrases, and certificates. The classic temptation is to build your own application-level encryption system. QoreDB makes a different choice: delegate secret storage to the operating system's native keychain, and focus effort on what the application actually controls, namely access control and leak prevention.
Two levels of separation
QoreDB strictly separates connection data into two categories. Non-sensitive metadata (connection name, host, port, driver, environment) is stored in a local JSON file (connections.json). This information doesn't need encryption and lets the interface load quickly.
Secrets (database passwords, SSH passwords, private-key passphrases) never pass through this file. They are stored exclusively in the system keychain: Apple Keychain on macOS, Credential Manager (DPAPI) on Windows, Secret Service (GNOME Keyring, KWallet) on Linux.
This separation means secrets are only retrieved at the moment a connection is actually established. The rest of the time, they exist nowhere in application memory.
Master password and Argon2
On top of the system keychain, QoreDB offers an optional master password. This password is hashed with Argon2 (random salt via OsRng, PHC format). The hash is stored in the keychain under a dedicated key.
The master password acts as an application-level lock: until it is provided at startup, no operation requiring credentials is allowed. This lock is volatile. It is lost on restart, which forces re-authentication at every session.
Choosing Argon2 as the hashing function makes brute-forcing extremely expensive. Combined with the system keychain that handles the actual encryption of credentials, this creates a defense in depth suited to desktop use.
Why delegate to the keychain rather than encrypt yourself
Native keychains are maintained by the security teams at Apple and Microsoft and by Linux maintainers. They benefit from regular audits and security updates, and integrate with biometric authentication mechanisms (Touch ID, Windows Hello). Reimplementing an application-level encryption system wouldn't provide a better level of security, and would introduce an additional attack surface to maintain.
Each QoreDB project uses an isolated keyring service, named after its project identifier. One project's credentials are not mixed with another's.
Sensitive<T>: preventing leaks in the code
Beyond storage, QoreDB protects credentials in memory with a dedicated Rust wrapper: Sensitive<T>. This type guarantees that secrets cannot leak accidentally. In Debug, Display and serialization, the value is replaced with REDACTED. To access the real value, the code must explicitly call expose(), which makes every access intentional and auditable in the source code.
Concretely, a password cannot end up in a structured log, an error message, or a serialized response by mistake. Rust's type system prevents it at compile time.
In practice
In day-to-day use, the vault is transparent. Credentials are retrieved on demand, the connection is established, and the secrets are immediately released. There is no cleartext cache, no temporary file, no in-memory persistence beyond the strict minimum.
The full flow: the user unlocks the vault (master password, or auto-unlock if none is configured), selects a connection, QoreDB retrieves the credentials from the keychain, establishes the connection, and releases the secrets. If the application restarts, the vault locks itself automatically.
Conclusion
QoreDB's vault rests on a simple principle: use the best tools available for each responsibility. Encryption is delegated to proven systems (OS keychains). Access control is handled by the application (master password + Argon2). Leak prevention is ensured by Rust's type system (Sensitive<T>). No secret is ever written in cleartext to disk, shown in logs, or kept in memory longer than necessary.
Stay updated on new releases
Subscribe to get product releases, new drivers notifications, and technical tutorials.

