In 2026, best practice is risk-based rotation: rotate database passwords every 30-90 days, API keys every 60 days, and user passwords only after confirmed breaches or during yearly audits – not on a fixed calendar schedule. Use dynamic secrets (HashiCorp Vault) for database credentials and automate API key rotation with expiration monitoring. This guide provides the complete rotation schedule by credential type, automation scripts, and monitoring configurations.
Why Rotation Still Matters
Even with the best password managers generating unique, complex credentials, rotation provides defense in depth. If a service experiences a breach, rotated credentials limit the window of exposure. High-privilege accounts, API keys, and service tokens particularly benefit from regular rotation schedules.
The key is applying rotation intelligently rather than mechanically. Not every credential needs the same treatment. A developer team’s production database credentials warrant different handling than a personal email account.
Risk-Based Rotation Schedules
The 2026 approach categorizes credentials by sensitivity and exposure risk:
| Credential Type | Rotation Frequency | Trigger Conditions |
|---|---|---|
| Database passwords | Every 30-90 days | After any staff change, on incident |
| API keys | Every 60 days | On deployment, after suspicious activity |
| Service accounts | Every 90 days | After team member departure |
| User passwords | As needed | After confirmed breaches, yearly audits |
| SSH keys | Every 180 days | On key compromise or离职 |
This table represents starting points. Adjust based on your threat model. Financial services and healthcare often face stricter regulatory requirements.
Automating Rotation with Password Managers
Modern password managers include rotation features that integrate directly with services. Here’s how to set up automated rotation:
Bitwarden CLI Rotation
# Generate and update a password for a specific entry
bw get item "Production Server" | jq '.id'
# Store the item ID
ITEM_ID="your-item-id-here"
# Generate new password and update
NEW_PASSWORD=$(bw generate -uln --length 24)
bw edit item $ITEM_ID --password "$NEW_PASSWORD"
# Sync to ensure vault is updated
bw sync
You can wrap this in a cron job or CI pipeline for automated rotation:
# Add to crontab for weekly rotation
0 2 * * 0 /usr/local/bin/rotate-secrets.sh >> /var/log/rotation.log 2>&1
HashiCorp Vault for Dynamic Secrets
For applications with database credentials, Vault’s dynamic secrets eliminate manual rotation entirely:
# Configure database secrets engine
vault secrets enable -path=my-database database
# Configure connection
vault write my-database/config/my-postgres \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@localhost:5432/mydb" \
allowed_roles="my-role"
# Create role with automatic rotation
vault write my-database/roles/my-role \
db_name=my-postgres \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';" \
default_ttl="1h" \
max_ttl="24h"
Applications request credentials from Vault, which generates unique, short-lived credentials automatically. When the TTL expires, Vault revokes and rotates the credentials without any manual intervention.
// Example: Fetching dynamic credentials in Go
import vault "github.com/hashicorp/vault/api"
func getDatabaseCredentials() (*vault.Secret, error) {
config := vault.DefaultConfig()
client, _ := vault.NewClient(config)
secret, err := client.Logical().Read("my-database/creds/my-role")
if err != nil {
return nil, err
}
return secret, nil
}
SSH Key Rotation
SSH keys warrant special attention for developers. Ed25519 keys offer better security than RSA while maintaining performance:
# Generate new Ed25519 key
ssh-keygen -t ed25519 -C "work-laptop-2026"
# Set key comment with date for tracking
# Output public key to add to servers
# Rotate keys on remote servers
for server in server1 server2 server3; do
ssh $server "echo '$(cat ~/.ssh/id_ed25519.pub)' >> ~/.ssh/authorized_keys"
done
For teams using a central CA, consider implementing SSH certificates instead of managing authorized_keys directly. This approach provides instant revocation and eliminates the need to update multiple servers when rotating keys.
API Key Management
API keys often receive less attention than user credentials but can expose significant attack surface. Implement these practices:
# Example: Rotating API keys in a Flask application
import os
import time
from datetime import datetime, timedelta
class APIKeyManager:
def __init__(self, db):
self.db = db
def rotate_key(self, user_id, key_id):
# Invalidate old key
self.db.execute(
"UPDATE api_keys SET active = FALSE WHERE id = ?",
(key_id,)
)
# Generate new key
new_key = os.urandom(32).hex()
expires_at = datetime.utcnow() + timedelta(days=90)
self.db.execute(
"""INSERT INTO api_keys
(user_id, key_hash, created_at, expires_at, active)
VALUES (?, ?, ?, ?, TRUE)""",
(user_id, hash(new_key), datetime.utcnow(), expires_at)
)
return new_key
def enforce_rotation(self, max_age_days=90):
cutoff = datetime.utcnow() - timedelta(days=max_age_days)
return self.db.execute(
"SELECT user_id, key_id FROM api_keys WHERE created_at < ? AND active = TRUE",
(cutoff,)
)
Store API keys in environment variables or secrets management, never in source code. Tools like Doppler or Infisical integrate with your development workflow to provide secret rotation without code changes.
Monitoring and Alerts
Rotation policies only work if you can verify compliance. Set up monitoring:
# Example: Prometheus alert for expiring credentials
groups:
- name: credential-expiry
interval: 24h
rules:
- alert: APICredentialExpiringSoon
expr: credential_expiry_timestamp - time() < 604800 # 7 days
for: 1h
labels:
severity: warning
annotations:
summary: "API credential expiring in less than 7 days"
- alert: SSHKeyNotRotated
expr: time() - ssh_key_last_rotated > 15552000 # 180 days
for: 24h
labels:
severity: critical
Service Account Rotation
Service accounts often cause the biggest headaches because they lack human owners. Implement a registry:
{
"service_accounts": [
{
"name": "ci-deployment",
"environment": "production",
"owner": "devops-team",
"last_rotated": "2026-02-15",
"rotation_interval_days": 30,
"credential_type": "service_principal"
},
{
"name": "backup-scheduler",
"environment": "staging",
"owner": "infrastructure",
"last_rotated": "2026-03-01",
"rotation_interval_days": 60,
"credential_type": "api_token"
}
]
}
Run periodic audits against this registry to identify neglected credentials.
Implementation Checklist
- Audit existing credentials - Know what you have before establishing rotation
- Categorize by risk - Not all credentials need the same schedule
- Implement automation - Manual rotation introduces human error
- Document exceptions - Some systems cannot rotate; document why and mitigate
- Test recovery procedures - Verify you can access systems after rotation
- Monitor compliance - Alert on credentials approaching rotation deadlines
- Review quarterly - Adjust schedules based on incident data and team feedback
Conclusion
Password rotation in 2026 focuses on automation, risk-based scheduling, and continuous monitoring rather than calendar-based mandates. Implement dynamic secrets where possible, automate API key rotation, and maintain clear ownership of all credentials. The goal isn’t rotation for its own sake—it’s limiting the blast radius when credentials inevitably leak.
Start with your highest-privilege credentials, automate what you can, and build from there. Small, consistent improvements beat comprehensive policies that nobody follows.
Related Reading
- Best Password Manager for Developers
- Bitwarden Vault Export and Backup Guide
- TOTP vs FIDO2 Authentication Explained
Built by theluckystrike — More at zovo.one