Skip to main content

Security Hardening

This guide covers security best practices for deploying FireBackup Enterprise in production environments. Follow these recommendations to protect your backup data and infrastructure.

Security Overview

FireBackup implements multiple layers of security:

Security Layers

Network Security:

  • TLS 1.3 encryption
  • Firewall rules
  • Rate limiting

Authentication:

  • Google OAuth 2.0
  • JWT tokens
  • Session management

Authorization:

  • Role-based access control
  • Organization isolation
  • Resource-level permissions

Data Protection:

  • AES-256-GCM encryption
  • Encryption at rest
  • Secure key management

Audit & Monitoring:

  • Audit logging
  • Activity monitoring
  • Alerting

TLS Configuration

Minimum Requirements

  • TLS 1.2 minimum (TLS 1.3 recommended)
  • Strong cipher suites only
  • Valid certificates from trusted CA

Nginx TLS Configuration

# Modern TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;

# Session settings
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

# Certificate chain
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;

# DH parameters (generate with: openssl dhparam -out dhparam.pem 4096)
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

Security Headers

# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# Content Security
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Content Security Policy
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.firebackup.io wss://api.firebackup.io;" always;

# Permissions Policy
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

Authentication Security

JWT Configuration

# Strong JWT secret (minimum 32 bytes)
JWT_SECRET=$(openssl rand -hex 32)

# Short token lifetime
JWT_EXPIRES_IN=24h

# Refresh token configuration
JWT_REFRESH_EXPIRES_IN=7d

OAuth Security

# Use HTTPS callback URLs only
GOOGLE_CALLBACK_URL=https://api.firebackup.io/api/v1/auth/google/callback

# Limit OAuth scopes
OAUTH_SCOPES=email,profile,https://www.googleapis.com/auth/firebase

Session Security

# Secure session configuration
SESSION_SECURE=true
SESSION_HTTP_ONLY=true
SESSION_SAME_SITE=strict
SESSION_MAX_AGE=86400000

Encryption

Backup Encryption

All backups are encrypted with AES-256-GCM:

Backup Process:

  1. Export data from Firebase
  2. Compress with Brotli
  3. Generate random IV (12 bytes)
  4. Encrypt with AES-256-GCM
  5. Append auth tag (16 bytes)
  6. Upload to storage

Key Management

# Generate encryption key
ENCRYPTION_KEY=$(openssl rand -hex 32)

# Store in secure location
# - Kubernetes Secret
# - AWS Secrets Manager
# - HashiCorp Vault
# - Azure Key Vault

Key Rotation

For Enterprise license, enable key rotation:

ENCRYPTION_KEY_ROTATION=true
ENCRYPTION_KEY_ROTATION_INTERVAL=90d
ENCRYPTION_OLD_KEYS=key1,key2,key3

Database Security

PostgreSQL Hardening

-- Disable remote root access
ALTER USER postgres PASSWORD 'strong-password';

-- Create application user with limited permissions
CREATE USER firebackup WITH PASSWORD 'secure-password';
GRANT CONNECT ON DATABASE firebackup TO firebackup;
GRANT USAGE ON SCHEMA public TO firebackup;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO firebackup;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO firebackup;

-- Enable row-level security (optional)
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;

Connection Security

# Use SSL connections
DATABASE_URL=postgresql://user:pass@host:5432/db?sslmode=verify-full

# Certificate verification
DATABASE_SSL_CA=/path/to/ca-certificate.crt
DATABASE_SSL_CERT=/path/to/client-cert.crt
DATABASE_SSL_KEY=/path/to/client-key.key

Redis Security

# Enable authentication
REDIS_URL=redis://:strong-password@redis:6379

# Use TLS
REDIS_URL=rediss://:password@redis:6379

# Disable dangerous commands (in redis.conf)
# rename-command FLUSHALL ""
# rename-command FLUSHDB ""
# rename-command DEBUG ""

Network Security

Firewall Rules

# Allow HTTPS only
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Redirect to HTTPS

# Internal services (adjust for your network)
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 4000 -j ACCEPT # API
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 5432 -j ACCEPT # PostgreSQL
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 6379 -j ACCEPT # Redis

# Drop all other traffic
iptables -A INPUT -j DROP

Kubernetes Network Policies

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: firebackup-api
namespace: firebackup
spec:
podSelector:
matchLabels:
app.kubernetes.io/component: api
policyTypes:
- Ingress
- Egress
ingress:
# Allow from ingress controller
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 4000
egress:
# Allow to PostgreSQL
- to:
- podSelector:
matchLabels:
app: postgresql
ports:
- protocol: TCP
port: 5432
# Allow to Redis
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
# Allow to external services (Firebase, storage)
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443

Rate Limiting

# API rate limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_WINDOW=60000
RATE_LIMIT_MAX=100

# Auth rate limiting (stricter)
AUTH_RATE_LIMIT_WINDOW=60000
AUTH_RATE_LIMIT_MAX=5

Nginx rate limiting:

# Define rate limit zones
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/m;
limit_conn_zone $binary_remote_addr zone=conn:10m;

# Apply rate limits
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_conn conn 20;
}

location /api/v1/auth/ {
limit_req zone=auth burst=5 nodelay;
}

Access Control

Role-Based Access Control (RBAC)

RolePermissions
OwnerFull organization access, billing, can delete
AdminManage members, projects, settings
MemberCreate/manage backups, schedules
ViewerRead-only access

Permission Matrix

ActionOwnerAdminMemberViewer
View backups
Create backups-
Restore backups-
Delete backups--
Manage projects--
Manage members--
Manage billing---
Delete org---

API Key Scopes

{
"permissions": [
"backups:read",
"backups:write",
"schedules:read",
"schedules:write",
"projects:read"
]
}

Audit Logging

Audit Events

All security-relevant actions are logged:

CategoryEvents
AuthenticationLogin, logout, failed attempts
AuthorizationPermission checks, access denied
Data AccessBackup create, restore, delete
ConfigurationSettings changes, member changes
AdminOrganization changes, billing

Log Format

{
"timestamp": "2024-01-15T10:30:45.123Z",
"level": "info",
"event": "backup.created",
"actor": {
"id": "user_abc123",
"email": "user@example.com",
"ip": "192.168.1.100"
},
"resource": {
"type": "backup",
"id": "bkp_xyz789"
},
"organization": "org_abc123",
"metadata": {
"projectId": "proj_abc123",
"type": "full"
}
}

Log Retention

# Retain audit logs
AUDIT_LOG_RETENTION_DAYS=365

# Export to external system
AUDIT_LOG_EXPORT=true
AUDIT_LOG_EXPORT_DESTINATION=s3://audit-logs/firebackup/

Secret Management

Kubernetes Secrets

apiVersion: v1
kind: Secret
metadata:
name: firebackup-secrets
namespace: firebackup
type: Opaque
stringData:
jwt-secret: "${JWT_SECRET}"
encryption-key: "${ENCRYPTION_KEY}"

Encrypt secrets at rest:

# EncryptionConfiguration
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: ${ENCRYPTION_KEY}
- identity: {}

External Secret Managers

AWS Secrets Manager:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: firebackup-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: SecretStore
target:
name: firebackup-secrets
data:
- secretKey: jwt-secret
remoteRef:
key: firebackup/production
property: JWT_SECRET

HashiCorp Vault:

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: firebackup-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: SecretStore
target:
name: firebackup-secrets
data:
- secretKey: jwt-secret
remoteRef:
key: secret/data/firebackup/production
property: JWT_SECRET

Container Security

Dockerfile Best Practices

# Use distroless base image
FROM gcr.io/distroless/nodejs20-debian12

# Run as non-root user
USER nonroot:nonroot

# Read-only filesystem
WORKDIR /app

# Copy only production files
COPY --chown=nonroot:nonroot dist/ ./dist/
COPY --chown=nonroot:nonroot node_modules/ ./node_modules/
COPY --chown=nonroot:nonroot package.json ./

# No shell access
CMD ["dist/main.js"]

Pod Security Standards

apiVersion: v1
kind: Pod
metadata:
name: firebackup-api
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: api
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}

Compliance

SOC 2 Readiness

ControlImplementation
Access ControlRBAC, OAuth, session management
EncryptionAES-256-GCM, TLS 1.3
Audit LoggingComprehensive event logging
AvailabilityMulti-zone deployment, backups
Change ManagementVersion control, CI/CD

GDPR Compliance

RequirementImplementation
Data EncryptionAll data encrypted at rest and in transit
Access ControlRole-based permissions
Data PortabilityExport functionality
Right to ErasureDelete user data capability
Audit TrailComplete audit logging

HIPAA Considerations

For healthcare data:

# Enhanced security settings
ENCRYPTION_ALGORITHM=aes-256-gcm
AUDIT_LOG_RETENTION_DAYS=2190 # 6 years
SESSION_TIMEOUT=1800000 # 30 minutes
FORCE_MFA=true

Security Checklist

Pre-Deployment

  • Generate strong secrets (JWT, encryption key)
  • Configure TLS with valid certificates
  • Set up database with SSL
  • Configure Redis authentication
  • Review firewall rules
  • Enable audit logging
  • Test authentication flow

Post-Deployment

  • Verify HTTPS redirect works
  • Test rate limiting
  • Review access logs
  • Set up monitoring alerts
  • Document incident response
  • Schedule security reviews

Ongoing

  • Rotate secrets quarterly
  • Update dependencies monthly
  • Review audit logs weekly
  • Conduct penetration testing annually
  • Security awareness training

Incident Response

Security Incident Procedure

  1. Detection: Alert triggered or user report
  2. Triage: Assess severity and scope
  3. Containment: Isolate affected systems
  4. Investigation: Analyze logs and evidence
  5. Remediation: Fix vulnerability
  6. Recovery: Restore normal operations
  7. Post-mortem: Document and improve

Contact Information

For security issues:


Next: High Availability - Multi-node deployment configuration.