How to use a secrets manager: Vault, AWS Secrets Manager, and dotenv-vault
secrets manager concepts, static vs dynamic secrets, secret rotation, Vault basics, AWS Secrets Manager SDK, HashiCorp Vault Node.js, least privilege IAM
Secrets Managers
Environment variables loaded from .env files work for development. In production, use a dedicated secrets manager: a centralized, audited store for credentials that handles rotation, access control, and audit logs.
AWS Secrets Manager
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');
const client = new SecretsManagerClient({ region: 'us-east-1' });
async function getSecret(secretName) {
const command = new GetSecretValueCommand({ SecretId: secretName });
const response = await client.send(command);
return JSON.parse(response.SecretString);
}
// Call at startup, cache in memory
let secrets;
async function loadSecrets() {
secrets = await getSecret('prod/myapp/database');
// secrets.DB_PASSWORD is now available in memory
}
Secret Rotation
Secrets managers support automatic rotation—they regenerate credentials on a schedule and update the stored value. Your application should re-fetch secrets periodically (or on connection error) rather than caching indefinitely. For database passwords, use short rotation intervals (7–30 days).
Least Privilege IAM
Your application should only have IAM permissions to read the specific secrets it needs, not all secrets. Use separate IAM roles for separate services. An IAM policy like:
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:us-east-1:123456789:secret:prod/myapp/*"
}