Secure storage for database credentials on macOS
Database URLs are compound secrets: they bundle host, user, password, sometimes SSL mode. One paste into the wrong Slack channel or a committed .env gives an attacker direct data access. On a Mac, your goals are: keep credentials out of Git, minimize plaintext lifetime, and scope credentials so dev laptops never hold production superuser passwords unless absolutely necessary.
1. Hook: DATABASE_URL is not “just config”
ORMs and frameworks read DATABASE_URL or discrete DB_HOST / DB_USER / DB_PASSWORD variables. That convenience trains teams to treat the string as boring — it is not. If it leaks:
- Attackers bypass your app and hit the database directly.
- Row-level security in the app does not apply to raw SQL connections.
OWASP Secrets Management Cheat Sheet applies directly: no secrets in source, rotate on exposure.
2. Tiered access model (recommended)
| Environment | Who holds credentials | Storage pattern |
|---|---|---|
| Local dev | Individual developer | Scoped dev DB user + vault or gitignored .env |
| CI | CI secret store | Injected env; never logged |
| Staging / prod | Platform IAM + secret manager | RDS IAM auth, Cloud SQL auth proxy, Vault dynamic DB creds, etc. |
Rule: production superuser strings should not live on laptops “for debugging.” Use read-only break-glass accounts with expiry and audit.
3. Where to store DATABASE_URL on macOS
Strong pattern — vault as source of truth
- Store
DATABASE_URL(or split fields) in PassStore under workspaceacme-api, groupdev. - Copy into a gitignored
.envonly for the active session or export in a dedicated terminal tab.
Benefits align with macOS Keychain for developers: OS-backed options reduce casual file theft vs a plaintext file that syncs everywhere.
Acceptable pattern — .env only (eyes open)
- Gitignored, verified.
- Dev-only user with no prod privileges.
- FileVault on; no cloud sync on repo root.
See where to store .env securely.
4. Prefer short-lived and scoped credentials when the platform allows
AWS RDS with IAM database authentication
AWS documents IAM-based authentication for RDS — tokens are time-limited compared to static passwords. Start from IAM database authentication for RDS (verify engine support).
Google Cloud SQL Auth Proxy
Instead of baking passwords into every laptop, many teams use the Cloud SQL Auth Proxy with IAM or rotated credentials.
PostgreSQL: per-app users
Create app_dev_makio with minimal grants — not postgres superuser — for local dev against shared dev clusters.
-- Illustrative — adjust to your schema
CREATE USER app_dev_makio WITH PASSWORD 'use-a-strong-random-password';
GRANT CONNECT ON DATABASE myapp_dev TO app_dev_makio;
GRANT USAGE ON SCHEMA public TO app_dev_makio;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_dev_makio;
5. Connection string hygiene
Do:
- Use TLS (
sslmode=require/ equivalent) for remote dev databases. - Keep passwords out of shell history where possible (
exportfrom a file withchmod 600or from vault paste).
Avoid:
- Logging the URL in app startup:
console.log(process.env.DATABASE_URL). - Storing the same URL in five tools (Docker, IDE, CLI, Postman, notes).
6. If credentials leaked
Follow recover from exposed database credentials — order is: revoke network paths (security groups / firewall), rotate passwords, audit logs, then clean up Git if the string was committed (accidentally committed).
7. Soft CTA
PassStore helps keep DATABASE_URL and related secrets encrypted at rest on your Mac, grouped per project — pair with the Git practices in keep secrets out of Git.