Database Credential Vault
Solo & TeamsGive the database introspection tools the credentials your apps already use — without ever putting a password in your config or in an AI agent's context. Servonaut scans a server for the DB credentials its applications already carry on disk, stores the password in your secret vault under a per-site label, and from then on resolves it by name.
The scan is read-only, the password is held server-side in staging and stored only in your vault, and only the masked preview ever reaches an AI agent — never the plaintext.
How it works
The introspection tools (db_processlist, db_top_queries)
need a database login. Instead of asking you to type one, Servonaut reads the
credentials your app already ships with and turns them into a reusable profile:
- Scan a server (read-only). Servonaut looks for the config files an app already has on disk and parses them locally.
- Review the redacted candidates. Only a masked preview (
pw=****xyz) and the connection shape (engine user@host:port/db) are shown — the plaintext password stays in server-side staging and is never rendered. - Label the credential. Each site gets a label derived from its config path (e.g.
shop.example.com). Accept it, edit it, or clear it for a single/default DB. - Store. The password goes to your secret vault; the non-secret connection metadata (
user,host,port,engine,database) goes to your local config. The two are recombined at connect time.
The vault holds just the password (under the name db/<instance>/<label>). The username, host, port, and database name are non-secret connection metadata kept in your local config and recombined at connect time — so if you open the vault entry on its own you'll see a password with no username, by design.
What the scan reads
The on-box command only lists and reads config files — find plus
sed, with a read-only sudo -n fallback for root-owned
files. It never writes. Credentials are discovered from:
| Source | What's read |
|---|---|
Dotenv (.env, .env.local, .env.production) | DATABASE_URL and environment-suffixed variants (DATABASE_URL_PROD, DATABASE_URL_STAGING), plus DB_*, POSTGRES_*, MYSQL_* fields |
| WordPress | wp-config.php — DB_NAME/DB_USER/DB_PASSWORD/DB_HOST |
| Joomla | configuration.php — the JConfig host/user/password/db |
| Magento | app/etc/env.php — the default connection block |
| Docker Compose | docker-compose*.yml / compose*.yaml — DB credentials in environment: blocks, resolving ${VAR} references against a co-located .env |
Because the reader falls back to a non-interactive sudo -n read, a dockerized app whose .env is owned by root — or whose live credentials live in a compose file's environment: block rather than a world-readable .env — is still discovered. A committed placeholder DATABASE_URL never shadows a real DATABASE_URL_PROD: the first password-bearing DSN wins.
Using a stored credential
Once stored, the introspection tools resolve the credential by name — no
password argument, no re-scan. When one instance hosts several databases,
name the site with app= (matched loosely: exact, then unique
prefix, then unique substring):
When an instance has several databases and you omit app, the tool
lists the stored sites so you can name one.
Coverage & management in the TUI
Day to day you scan, store, and prune credentials without leaving the TUI:
| Where | Action |
|---|---|
| Server Actions → Scan DB creds | Scan the selected instance, review masked candidates, and store one. Already-vaulted sites are flagged on re-scan. |
| Store flow | A label prompt (pre-filled with the derived label) lets you name each site — give a prod and a staging DB on the same site distinct labels. |
| Secrets → DB coverage | One row per stored site (Server · Site · Secret · status) so you can see which instances are covered and which are gaps across the fleet. |
| DB coverage → d | Remove a stored credential, with an optional "also delete the secret from the vault" toggle. |
The same flow is scriptable from the CLI with servonaut db setup
<instance>.
For AI agents (MCP)
AI agents drive the whole flow through the Servonaut MCP server. The plaintext password never enters an agent's context: a scan stages candidates server-side and returns only masked previews plus an opaque staging token; a save commits the chosen token into your vault.
| Tool | Guard | What it does |
|---|---|---|
db_setup_scan | standard | Discover DB credentials on a host (read-only) and stage them; returns redacted previews only. |
db_setup_save | standard | Commit a staged credential into the secret store under a per-site label and write a reusable profile. Confirmation required. |
db_setup_remove | standard | Remove a saved DB profile (and, by default, its stored secret). |
db_processlist / db_top_queries | readonly | Resolve the stored credential by name and report live query activity. |
See the MCP server docs for the full tool list and guard-level matrix, and Secrets & Integrations for configuring the vault the passwords are stored in.
Security model
- The scan is read-only — the on-box command only lists and reads config files; it never writes, even with the
sudo -nfallback. - The password never enters an AI agent's context — candidates are held in server-side staging; agents and the audit trail only ever see the masked preview and the opaque staging token.
- Only the password is encrypted in the vault — the username, host, port, and database name are non-secret connection metadata kept in your local config.
- Requires a configured secret store — the vault is the same one used for Secrets & Integrations (Solo and Teams plans).