Security Best Practices
Security guidelines for SelfHostedDB deployments
This guide covers security best practices for deploying and operating SelfHostedDB in production environments.
Table of Contents
- Authentication Security
- Database Security
- Network Security
- Container Security
- Secrets Management
- SSL/TLS Configuration
- Security Checklist
Authentication Security
HTTP Basic Authentication
Best Practices:
-
Use Strong Passwords:
# Generate strong password (Linux/Mac) openssl rand -base64 32 # Windows PowerShell [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })) -
Change Default Credentials:
- Never use default
admin/secretin production - Use environment variables, not hardcoded values
- Rotate passwords regularly (every 90 days)
- Never use default
-
Password Requirements:
- Minimum 16 characters
- Mix of uppercase, lowercase, numbers, symbols
- No dictionary words
- No personal information
-
Storage:
- Store in secrets manager (AWS Secrets Manager, Azure Key Vault, etc.)
- Never commit to version control
- Use different credentials per environment
API Keys
Best Practices:
-
Key Generation:
- Keys are automatically generated (64-character hex strings)
- Cryptographically secure random generation
- Store keys securely (only shown once on creation)
-
Key Management:
- Use descriptive key names
- Rotate keys regularly
- Revoke compromised keys immediately
- Use different keys for different services/environments
-
Key Types:
anon: For read-only access (when applicable)service_role: For full access (use sparingly)
-
Storage:
- Store in environment variables or secrets manager
- Never log or expose in error messages
- Use HTTPS for all API requests
Database Security
Connection Security
-
Use SSL/TLS:
# Always use SSL in production DATABASE_URL=postgres://user:pass@host:5432/db?sslmode=require -
Connection String Security:
- Never hardcode connection strings
- Use environment variables or secrets manager
- Rotate database passwords regularly
-
Database User Permissions:
- Use least privilege principle
- Create dedicated users for application
- Grant only necessary permissions
- Avoid using superuser accounts
SQL Injection Prevention
The application uses parameterized queries to prevent SQL injection:
// ✅ SAFE: Parameterized query
await pool.query('SELECT * FROM users WHERE id = $1', [userId]);
// ❌ DANGEROUS: String concatenation (never do this)
await pool.query(`SELECT * FROM users WHERE id = ${userId}`);All endpoints use parameterized queries. However, be cautious with:
- Table names (validated with regex)
- Schema names (validated with regex)
- Custom SQL queries (user-provided)
Database Access Control
-
Network Isolation:
- Use private subnets for databases
- Restrict database port (5432) to app containers only
- Use security groups/firewall rules
-
Connection Pooling:
- Limit connection pool size
- Monitor active connections
- Set appropriate timeouts
Network Security
Firewall Configuration
Recommended Rules:
-
Application Server:
- Allow inbound: Port 3001 (or 80/443 with reverse proxy)
- Allow inbound: SSH (port 22) from trusted IPs only
- Allow outbound: Port 5432 to database
-
Database Server:
- Allow inbound: Port 5432 from application servers only
- Block all other inbound traffic
- Use security groups (cloud) or iptables (self-hosted)
HTTPS Configuration
Always use HTTPS in production:
-
Reverse Proxy (nginx):
server { listen 443 ssl http2; server_name your-domain.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://localhost:3001; } } -
Let's Encrypt (Free SSL):
sudo certbot --nginx -d your-domain.com -
Cloud Load Balancers:
- AWS: Application Load Balancer with ACM certificate
- Azure: App Gateway with SSL certificate
- GCP: Cloud Load Balancer with managed SSL
HSTS Headers
Enable HTTP Strict Transport Security:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;Container Security
Image Security
-
Base Images:
- Use official, minimal base images (
node:18-slim) - Regularly update base images
- Scan images for vulnerabilities
- Use official, minimal base images (
-
Image Scanning:
# Using Trivy trivy image selfhosteddb:latest # Using Snyk snyk test --docker selfhosteddb:latest -
Multi-stage Builds:
- Use multi-stage builds to reduce image size
- Exclude unnecessary files from final image
- Don't include secrets in images
Runtime Security
-
Non-root User:
- Run containers as non-root user (if possible)
- Use read-only filesystems where applicable
-
Resource Limits:
# docker-compose.yml services: app: deploy: resources: limits: cpus: '1' memory: 2G -
Container Isolation:
- Use separate networks for different services
- Limit container capabilities
- Use security profiles
License System Security
License Key Storage
Local License Cache:
- License keys are stored locally in
license.jsonfile - Optionally encrypted using
LICENSE_ENCRYPTION_KEYenvironment variable - Recommended to encrypt in production deployments
Encryption Setup:
# Generate encryption key
openssl rand -hex 32
# Set in environment
LICENSE_ENCRYPTION_KEY=your-generated-key-hereLicense Server Communication
HTTPS Required:
- Always use HTTPS for
LICENSE_SERVER_URLin production - License validation requests are sent over HTTPS
- Prevents man-in-the-middle attacks
Example:
# Production
LICENSE_SERVER_URL=https://license.yourdomain.com
# Development (local testing)
LICENSE_SERVER_URL=http://localhost:3002License Validation
Email-Based Validation:
- License keys are tied to purchaser's email address
- Prevents license sharing between different owners
- Same owner can deploy on unlimited machines/platforms
Best Practices:
- Store
LICENSE_SERVER_URLin environment variables - Use HTTPS for license server communication
- Encrypt local license cache in production
- Rotate
LICENSE_ENCRYPTION_KEYif compromised
Secrets Management
Never Do This
❌ Hardcode secrets in code:
// BAD
const password = "my-secret-password";❌ Commit secrets to Git:
# BAD - .env file in repository
git add .env❌ Include secrets in Docker images:
# BAD
ENV AUTH_PASS=secret123❌ Share secrets via email/chat:
- Use secure channels only
Best Practices
✅ Use Secrets Managers:
AWS:
# Store secret
aws secretsmanager create-secret \
--name selfhosteddb/auth-pass \
--secret-string "your-password"
# Use in ECS/EKS
# Reference in task definition or Kubernetes secretsAzure:
# Store in Key Vault
az keyvault secret set \
--vault-name selfhosteddb-vault \
--name auth-pass \
--value "your-password"GCP:
# Store in Secret Manager
echo -n "your-password" | gcloud secrets create auth-pass --data-file=-✅ Use Environment Variables:
# At runtime (not in image)
docker run -e AUTH_PASS="$(cat secret.txt)" selfhosteddb:latest✅ Rotate Secrets Regularly:
- Rotate passwords every 90 days
- Rotate API keys every 90 days
- Update database passwords regularly
SSL/TLS Configuration
Database SSL
Always use SSL for database connections in production:
# Connection string with SSL
DATABASE_URL=postgres://user:pass@host:5432/db?sslmode=requireSSL Modes:
sslmode=require- Require SSL (recommended)sslmode=prefer- Prefer SSL, fallback to non-SSLsslmode=verify-full- Require SSL and verify certificatesslmode=disable- Disable SSL (not recommended)
Application SSL
Use HTTPS for all API requests:
-
Development:
- Can use HTTP for local development
- Never use HTTP in production
-
Production:
- Always use HTTPS
- Redirect HTTP to HTTPS
- Use valid SSL certificates
- Enable HSTS headers
Security Checklist
Pre-Deployment
- Changed default
AUTH_USERandAUTH_PASS - Generated strong passwords (16+ characters)
- Database connection uses SSL (
?sslmode=require) - Secrets stored in secrets manager (not in code)
- Firewall rules configured
- HTTPS enabled (reverse proxy or load balancer)
-
.envfile excluded from Git and Docker images - Database user has least privilege permissions
Post-Deployment
- Test authentication with new credentials
- Verify HTTPS is working
- Test database SSL connection
- Monitor logs for suspicious activity
- Set up security alerts
- Document security procedures
- Plan for incident response
Ongoing Maintenance
- Rotate passwords every 90 days
- Rotate API keys every 90 days
- Update Docker images regularly
- Scan images for vulnerabilities
- Review access logs
- Update dependencies (npm audit)
- Monitor for security advisories
Common Security Mistakes
1. Default Credentials
Mistake: Using default admin/secret in production
Fix: Always change default credentials before deployment
2. Exposed Secrets
Mistake: Committing .env files or hardcoding secrets
Fix: Use secrets manager, never commit secrets
3. No SSL/TLS
Mistake: Using HTTP or unencrypted database connections
Fix: Always use HTTPS and database SSL in production
4. Weak Passwords
Mistake: Using simple, guessable passwords
Fix: Use password generator, enforce strong passwords
5. Overly Permissive Database User
Mistake: Using superuser or overly permissive database user
Fix: Create dedicated user with least privilege
Incident Response
If Credentials Are Compromised
-
Immediately:
- Rotate all compromised credentials
- Revoke affected API keys
- Review access logs
-
Investigation:
- Check for unauthorized access
- Review database logs
- Check for data exfiltration
-
Remediation:
- Update all credentials
- Patch vulnerabilities
- Improve security measures
If Database Is Compromised
-
Immediately:
- Isolate affected systems
- Change all database passwords
- Review database access logs
-
Recovery:
- Restore from backup if needed
- Verify data integrity
- Update security measures
Security Monitoring
Log Monitoring
Monitor logs for:
- Failed authentication attempts
- Unusual query patterns
- High error rates
- Suspicious IP addresses
Tools
- AWS: CloudWatch Logs, GuardDuty
- Azure: Application Insights, Security Center
- GCP: Cloud Logging, Security Command Center
- Self-hosted: ELK Stack, Grafana Loki
Related Documentation
- Production Deployment Guide - Secure deployment practices
- API Documentation - API security
- Troubleshooting Guide - Security-related issues
- Installation Guide - Secure installation
Security Resources:
- Deploying to production? See Production Guide for secure deployment
- Using the API? Review API Authentication for secure API usage
- Need help? Check Troubleshooting Guide for security issues
Additional Resources
- OWASP Top 10 (opens in a new tab)
- PostgreSQL Security (opens in a new tab)
- Docker Security (opens in a new tab)
- Node.js Security Best Practices (opens in a new tab)
Last Updated: 2025-01-27