Password Management
Password Management
Section titled “Password Management”DBCrust remembers database passwords for all supported database types. Saved passwords live in the secret store (OS keychain, or a passphrase-encrypted file on Linux) — see Secret Storage. The older universal .dbcrust file is still read (and can be migrated with dbcrust secrets migrate) but DBCrust never writes to it or encrypts it any more.
🔐 Overview
Section titled “🔐 Overview”The password management system provides:
- Universal Support: Works with PostgreSQL, MySQL, MongoDB, Elasticsearch, ClickHouse
- Automatic Lookup: Searches for passwords when connecting without credentials: the secret store first, then the legacy
.dbcrustfile, then.pgpass/.my.cnf - Authentication Retry: Prompts for password on auth failure and saves it to the secret store
- Target-bound: A stored password is only used for the exact engine, host, port, database and user it was saved for
- Cross-Platform: macOS Keychain, Windows Credential Manager, Argon2id passphrase file on Linux
📁 Legacy .dbcrust File Format (read-only)
Section titled “📁 Legacy .dbcrust File Format (read-only)”Older versions saved passwords in ~/.dbcrust. DBCrust still reads it as a fallback; new passwords go to the secret store instead. Run dbcrust secrets migrate to move existing entries. The file uses the format:
database_type:host:port:database:username:passwordExamples
Section titled “Examples”# PostgreSQL - plaintext passwordpostgresql:localhost:5432:myapp:dbuser:mypassword
# MySQL - legacy machine-key value (prefixed with 'enc:'; readable, never written)mysql:db.example.com:3306:webapp:admin:enc:a1b2c3d4e5f6789...
# MongoDB clustermongodb:cluster.mongodb.net:27017:analytics:analyst:secret123
# Wildcard matching - any host, port, user for specific databasepostgresql:*:*:testdb:*:development_password
# Elasticsearch with custom portelasticsearch:es.cluster.com:9200:logs:elastic_user:elastic_pass
# ClickHouseclickhouse:ch.example.com:8123:analytics:analyst:ch_passwordWildcard Support
Section titled “Wildcard Support”Use * to match any value for that field. Wildcards are a legacy feature: dbcrust secrets migrate never converts them automatically (a wildcard would hand one password to every matching target); it lets you bind one to a concrete target instead.
# Match any host/port for testdb databasepostgresql:*:*:testdb:testuser:testpass
# Match any database for specific user on hostmysql:localhost:*:*:admin:admin_pass
# Match any user on localhost PostgreSQLpostgresql:localhost:5432:myapp:*:shared_password🗂️ File Location
Section titled “🗂️ File Location”| Platform | Default Location | Custom Location |
|---|---|---|
| Linux/macOS | ~/.dbcrust | $DBCRUST_PASSFILE |
| Windows | %USERPROFILE%\.dbcrust | %DBCRUST_PASSFILE% |
Security
Section titled “Security”- Unix/macOS: A legacy file readable by other users is refused; keep it at
0600 - Windows: Relies on NTFS directory security and file system permissions
dbcrust secrets auditreports plaintext andenc:lines and loose permissions
🔄 Automatic Password Flow
Section titled “🔄 Automatic Password Flow”DBCrust automatically manages passwords through this flow:
graph TD A[Connect to Database] --> B{Password in URL?} B -->|Yes| C[Use Provided Password] B -->|No| D[Lookup: secret store, then legacy .dbcrust, then pgpass / my.cnf] D --> E{Password Found?} E -->|Yes| F[Try Connection with Found Password] E -->|No| G[Prompt for Password] F --> H{Connection Success?} H -->|Yes| I[Connected Successfully] H -->|No| G C --> J{Connection Success?} J -->|Yes| I J -->|No| G G --> K[Try Connection with Entered Password] K --> L{Connection Success?} L -->|Yes| M[Save password to the secret store] L -->|No| N[Authentication Failed] M --> O[Password stored, bound to the target] O --> IExample Flow
Section titled “Example Flow”# 1. Connect without password❯ dbcrust postgres://postgres@localhost:5432/postgres
# 2. Authentication fails, automatic prompt appears🔐 Password: [hidden input]
# 3. Password accepted, automatically saved to the secret store✅ Password saved to the secure store✓ Successfully connected to database
# 4. Next time: automatic connection using saved password❯ dbcrust postgres://postgres@localhost:5432/postgres✓ Successfully connected to database # Uses saved passwordSaved Sessions with Dynamic Password Commands
Section titled “Saved Sessions with Dynamic Password Commands”Saved sessions never store password values in sessions.toml, but they can store a command that prints the password to stdout. This is useful for Vault, cloud CLIs, password managers, and other rotating-secret workflows.
\ss chpprd --password-command vault kv get -mount=secret -field=password preprod/gim/admin/clickhouse/default-userThen reconnect normally:
dbc session://chpprdDBCrust runs the command only during reconnection, trims the trailing newline, injects the result as the password, and does not persist the command output. Only configure commands you trust in sessions.toml.
You can also edit ~/.config/dbcrust/sessions.toml directly:
[sessions.chpprd]host = "hh8mmc7lqc.us-west-2.aws.clickhouse.cloud"port = 8443user = "default"dbname = "gim"database_type = "ClickHouse"
[sessions.chpprd.options]secure = "true"password_command = "vault kv get -mount=secret -field=password preprod/gim/admin/clickhouse/default-user"🛠️ Interactive Commands
Section titled “🛠️ Interactive Commands”\savepass - Save Password
Section titled “\savepass - Save Password”Interactively save a password to the secret store:
postgres@myapp=> \savepassDatabase type: postgresqlHost: localhostPort: 5432Database name: myappUsername: postgresPassword: [hidden input]Password saved for postgresql:postgres@localhost:5432/myapp (secure store)Features:
- Interactive prompts for all connection details
- Default values provided based on common database ports
- The password is stored in the OS keychain / encrypted file, bound to this exact target
- Updates the existing entry if found
\listpass - List Stored Passwords
Section titled “\listpass - List Stored Passwords”Display all stored credentials without showing the actual passwords. Entries still in the legacy .dbcrust file are marked (legacy):
postgres@myapp=> \listpassSaved passwords: postgresql:postgres@localhost:5432/myapp mysql:admin@db.example.com:3306/webapp mongodb:analyst@cluster.mongodb.net:27017/analytics (legacy)
(legacy) entries are still in ~/.dbcrust — run `dbcrust secrets migrate` to move them into the secure store.\deletepass - Delete Password
Section titled “\deletepass - Delete Password”Interactively select and remove a stored password:
postgres@myapp=> \deletepassSelect password to delete: 1. postgresql:postgres@localhost:5432/myapp 2. mysql:admin@db.example.com:3306/webapp 3. mongodb:analyst@cluster.mongodb.net:27017/analytics
Selection: 2Password deleted: mysql:admin@db.example.com:3306/webapp\encryptpass - Deprecated
Section titled “\encryptpass - Deprecated”DBCrust no longer encrypts .dbcrust: its machine-derived key could be recomputed by any process of your user, so it protected nothing. The command now just points to the replacement:
postgres@myapp=> \encryptpassDBCrust no longer encrypts ~/.dbcrust ... Run `dbcrust secrets migrate` to move existing entries🔒 Security Model
Section titled “🔒 Security Model”Saved passwords are protected by the secret store, not by a key derived from your machine:
- macOS / Windows: the OS keychain (service
dbcrust.store). - Linux:
secrets.enc, AES-256-GCM under an Argon2id key derived from a passphrase only you know; the unlocked key is cached in the kernel session keyring until you log out (dbcrust secrets unlock/lock). - Bound to the target: the record stores engine, host, port, database, user and TLS mode, and is refused for any other target.
- Never plaintext, never machine-derived: legacy
enc:values are only ever decrypted to be migrated. - Memory: secret values are zeroized after use.
See Secret Storage for the threat model, dbcrust secrets audit and the migration walk-through.
🌐 Cross-Platform Usage
Section titled “🌐 Cross-Platform Usage”# First connect: prompts for the DB password, then (once) for a passphrase# that protects ~/.config/dbcrust/secrets.encdbcrust postgres://postgres@localhost:5432/myapp
# Later runs: unlock once per login session, then connect without promptsdbcrust secrets unlockdbcrust -c 'select 1' postgres://postgres@localhost:5432/myappmacOS and Windows
Section titled “macOS and Windows”# First connect saves the password in the OS keychain / Credential Managerdbcrust postgres://postgres@localhost:5432/myapp# Later runs connect without promptingdbcrust postgres://postgres@localhost:5432/myapp🔧 Advanced Configuration
Section titled “🔧 Advanced Configuration”Custom Legacy Password File Location
Section titled “Custom Legacy Password File Location”Set the DBCRUST_PASSFILE environment variable to point the (read-only) legacy lookup and dbcrust secrets migrate at another file:
Linux/macOS
export DBCRUST_PASSFILE="/path/to/my/custom/passwords"dbcrust postgres://postgres@localhost:5432/myappWindows
$env:DBCRUST_PASSFILE = "C:\path\to\my\custom\passwords"dbcrust postgres://postgres@localhost:5432/myappEscaping Special Characters (legacy file)
Section titled “Escaping Special Characters (legacy file)”If credentials in a legacy .dbcrust file contain colons (:) or backslashes (\), escape them:
# Host with colon in namepostgresql:host\\:with\\:colons:5432:db:user:pass
# Password with colonpostgresql:localhost:5432:db:user:pass\\:with\\:colon
# Database name with backslashpostgresql:localhost:5432:db\\name:user:passwordTeam Workflows
Section titled “Team Workflows”For team environments, consider these patterns:
- Individual stores: every team member keeps their own secret store; nothing secret is shared through git.
- Shared credentials: use environment variables, Vault (
vault://) or apassword_commandfor shared database credentials. - Role-based access: save one password per database role (the store keeps one record per user/host/port/database).
🐛 Troubleshooting
Section titled “🐛 Troubleshooting”Common Issues
Section titled “Common Issues”Password Not Found
Section titled “Password Not Found”# Where do saved secrets live, and is the store locked?dbcrust secrets status
# The stored password is bound to the exact host, port, database and user# it was saved for: a different host (or user) prompts again.Secret storage is locked
Section titled “Secret storage is locked”# Linux file backend: enter the passphrase once for this login sessiondbcrust secrets unlock# One-shot (-c/-f), --no-input and the desktop app never prompt: they report "locked"Forgot the passphrase
Section titled “Forgot the passphrase”# secrets.enc cannot be recovered. Remove it and save your passwords again:rm ~/.config/dbcrust/secrets.enc ~/.config/dbcrust/secrets_index.tomlLegacy enc: value cannot be decrypted
Section titled “Legacy enc: value cannot be decrypted”# It was encrypted on another machine (or with another hostname/user).# `dbcrust secrets migrate` keeps such lines untouched; re-enter the password:dbcrust postgres://postgres@localhost:5432/myappPermission Denied on the legacy file (Unix/macOS)
Section titled “Permission Denied on the legacy file (Unix/macOS)”chmod 600 ~/.dbcrustConnection Still Fails
Section titled “Connection Still Fails”# Verify the stored credentials work manuallydbcrust postgres://username:password@host:port/database
# Check if authentication error detection is workingdbcrust postgres://wronguser@localhost:5432/postgres# Should prompt for passwordDebug Mode
Section titled “Debug Mode”Enable debug logging to troubleshoot password lookup:
# In ~/.config/dbcrust/config.toml[logging]level = "debug"console_output = trueThen check the logs for password lookup activity:
DEBUG [dbcrust] Looking up a saved passwordDEBUG [dbcrust] Found a saved passwordDEBUG [dbcrust] Connection successful with looked-up password🔗 Related Features
Section titled “🔗 Related Features”- Secret Storage: Where passwords live,
dbcrust secrets status|audit|migrate|unlock|lock - Vault Integration: For dynamic database credentials
- Session Management: Save complete connection configurations
- Security: Overall security best practices
- Configuration: General configuration options