Your Database Password Is 18 Months Old. That's a Problem.
Your Database Password Is 18 Months Old. That's a Problem.
That production database password? It was set when the project started. Three people who've since left the company know it. It's in someone's .env.local, a Slack DM from last year, and that wiki page nobody updates.
This is how most teams manage database credentials. And it's exactly how breaches happen.
The Static Password Problem
Static credentials compound risk over time:
Credential sprawl: Every copy of that password is a potential leak. Local environments, CI configs, deployment scripts, that "temporary" Notion doc.
Unlimited blast radius: Compromised credentials stay valid until someone manually rotates. Could be days. Could be never.
Ex-employee access: Everyone who ever had production access still has it—unless you've rotated since they left.
Compliance failures: SOC 2, PCI DSS, HIPAA all require credential rotation. "We'll get to it" doesn't satisfy auditors.
Why Manual Rotation Fails
Teams that try manual rotation usually give up:
- Generate password, update database, update secrets, verify, clean up
- Miss one service and it breaks at 2am
- "We rotate quarterly" becomes "we rotated that one time"
- Nobody wants to be the one who takes down production
The answer isn't "try harder at manual rotation." It's automation.
The Two-Secret Strategy
Zero-downtime rotation requires two valid credentials at all times:
Before: [user_a: active] [user_b: active]
Step 1: Create user_c, verify it works
Step 2: Drop user_a
After: [user_b: active] [user_c: active]
Your application always has valid credentials. During rotation, both old and new work briefly. Connection pools drain naturally while new connections use updated creds.
Setting Up Automatic Rotation
KeyEnv handles the entire rotation lifecycle. Here's the setup:
1. Create a rotation
# In the web app: Project → Rotations → Create Rotation
# Select PostgreSQL or MySQL
# Enter your admin credentials (stored encrypted)
# Set rotation interval (start with 30 days)
2. KeyEnv creates managed credentials
After setup, KeyEnv creates two database users and injects them as environment variables:
MYDB_HOST=db.example.com
MYDB_PORT=5432
MYDB_DATABASE=production
MYDB_USERNAME=keyenv_a3f8c1d2
MYDB_PASSWORD=7f2a9b4c8e1d3f5a... # 64 random chars
MYDB_URL=postgresql://keyenv_a3f8c1d2:[email protected]:5432/production
3. Pull credentials in your app
# Pull to .env
keyenv pull
# Or inject directly (credentials never hit disk)
keyenv run -- npm start
4. Rotation happens automatically
On schedule, KeyEnv:
- Generates new username + 64-char password
- Creates the user in your database
- Grants permissions
- Verifies the new credentials work
- Updates your environment variables
- Drops the old user
Your next deploy gets fresh credentials. No manual steps.
What About Private Databases?
Most production databases aren't publicly accessible. They're in private VPCs, behind firewalls.
KeyEnv supports Lambda proxy connections:
┌─────────────┐ ┌────────────────┐ ┌──────────────┐
│ KeyEnv │────▶│ Your Lambda │────▶│ Private DB │
│ API │ │ (in your VPC) │ │ │
└─────────────┘ └────────────────┘ └──────────────┘
Deploy a small Lambda in your VPC. KeyEnv sends HMAC-signed requests with timestamp validation. Your database never touches the public internet.
When Things Go Wrong
Rotations can fail. Network issues, permission changes, database maintenance.
KeyEnv handles failures gracefully:
- Automatic rollback: If new credentials can't be verified, old ones stay active
- Webhook notifications: Get alerted immediately on failure
- Error categorization: Auth errors vs access errors vs transient issues
- Retry logic: Temporary failures retry automatically
# Check rotation status
# Project → Rotations → [your rotation] → History tab
The Compliance Angle
If you're pursuing SOC 2, PCI DSS, or similar:
- SOC 2 CC6.1: Credential management controls
- PCI DSS 8.2.4: Change passwords at least every 90 days
- HIPAA: Technical safeguards for access control
Automatic rotation gives you documented schedules, audit trails, and evidence of credential lifecycle management. Your auditor sees "credentials rotate automatically every 30 days" instead of "we rotate when we remember."
Best Practices
Start conservative: 30-day intervals while you validate. Shorten once confident.
Test in staging first: Run a few rotation cycles before enabling production.
Use connection pooling: Pools handle credential changes more gracefully than direct connections.
Set up webhooks: Know immediately when something breaks.
Review history: Check for patterns in failures or timing issues.
See the full rotation documentation for detailed setup instructions.
The Bottom Line
Static database passwords are technical debt that compounds. The longer they exist, the more places they spread, the greater the risk when (not if) they leak.
Automatic rotation isn't just security hygiene—it's eliminating a category of operational burden. No more "who has the production password?" No more post-departure rotations. No more audit findings.
keyenv login
# Then: Project → Rotations → Create Rotation
Your 18-month-old password has earned its retirement.
TL;DR: Static database passwords spread everywhere and stay valid forever. Set up automatic rotation with keyenv and stop thinking about it.