DBdock handles sensitive data — database credentials, API keys, and backup contents. This page covers the security features built in and the practices we recommend for production use.
Secrets never live in the config file
DBdock enforces a strict split:
Lives in dbdock.config.json | Lives in .env |
|---|
| Host, port, database name, username | Database password |
| Bucket names, regions | Storage access keys |
| SMTP host, port, sender addresses | SMTP credentials |
| Slack enabled/disabled | Slack webhook URL |
| Encryption enabled flag | Encryption secret |
Commit dbdock.config.json to your repository. Never commit .env.
Strict mode
Enable strict mode to have DBdock refuse to run if any secret appears in the config file:
Use in CI and production as a safety net against accidental secret leaks.
Encryption
Algorithm
- AES-256-GCM (authenticated encryption)
- Key derived from
DBDOCK_ENCRYPTION_SECRET via PBKDF2 (100,000 iterations by default)
- Unique IV per backup
- Authentication tag stored with the ciphertext
GCM authenticates the ciphertext, so tampered backups fail to decrypt rather than silently producing garbage data.
Generate an encryption key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
The key must be exactly 64 hexadecimal characters (0–9, a–f).
Where to store the key
- Not in the backup destination. An attacker with your S3 bucket should not also have the key.
- Not in the repository.
.env is gitignored for a reason.
- A password manager, secret vault, or cloud KMS is ideal.
Losing the key = losing the backup. There is no recovery path for encrypted backups without the key. Back up the key somewhere safe before you rely on encryption in production.
Rotating the key
See the Key rotation guide for the full procedure. The short version: decrypt old backups with the old key, re-encrypt with the new one.
Credential masking
DBdock masks credentials in log output by default. You’ll see entries like:
Connecting to postgresql://postgres:****@host:5432/db
instead of the real password. This helps prevent accidents when pasting logs into issues or sharing screens.
Using .pgpass
For host-level credential isolation, use PostgreSQL’s native .pgpass file:
touch ~/.pgpass
chmod 600 ~/.pgpass
echo "host:port:database:user:password" >> ~/.pgpass
DBdock uses .pgpass automatically when present. Environment variables take priority if both are set.
.pgpass is useful when:
- Multiple tools need the same credentials
- You want OS-level file permissions gating access
- You share a machine across environments
Storage provider best practices
AWS S3 / R2
Create a dedicated IAM user or R2 API token for DBdock with least privilege:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::my-dbdock-backups",
"arn:aws:s3:::my-dbdock-backups/*"
]
}
]
}
- Enable server-side encryption on the bucket (SSE-S3 or SSE-KMS)
- Block public access
- Enable versioning for ransomware protection
- Set up lifecycle rules to move old backups to Glacier if you want long retention
Local storage
- The backup directory should have
0700 permissions (owner read/write/execute only)
- The user running DBdock should own the directory
- Filesystem-level encryption (LUKS, FileVault, BitLocker) protects against stolen hardware
CI/CD considerations
When running DBdock in CI:
- Use secret managers (GitHub Actions secrets, Vault, AWS Secrets Manager) — never commit secrets
- Prefer
DBDOCK_DB_URL over separate variables for fewer leakable values
- Enable strict mode
- Use read-only database credentials for logical backups where possible
Reporting security issues
Do not file public GitHub issues for vulnerabilities.
See the full SECURITY.md for response timelines.