Overview
CaseBender ships with secure defaults, but your deployment environment requires additional hardening. This guide provides recommendations for securing the infrastructure surrounding CaseBender.
This guide covers infrastructure hardening. CaseBender’s application-level security (encryption, RBAC, audit logging) is configured within the application itself. See the relevant security documentation pages for application configuration.
TLS Configuration
Reverse Proxy
CaseBender should be deployed behind a reverse proxy (Nginx, Caddy, Traefik, or cloud load balancer) that terminates TLS:
Recommended TLS Settings:
| Setting | Value |
|---|
| Minimum TLS Version | TLS 1.2 (TLS 1.3 preferred) |
| Cipher Suites | AEAD ciphers only (AES-256-GCM, ChaCha20-Poly1305) |
| HSTS | Enabled with max-age=31536000; includeSubDomains |
| OCSP Stapling | Enabled |
| Certificate Type | RSA 2048+ or ECDSA P-256+ |
Nginx Example:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Certificate Management
- Use certificates from a trusted Certificate Authority (Let’s Encrypt, DigiCert, etc.)
- Automate certificate renewal (certbot, cert-manager)
- Monitor certificate expiration with alerting (minimum 30 days before expiry)
- Use separate certificates for internal services if implementing mutual TLS
Database Security
PostgreSQL Hardening
| Setting | Recommendation |
|---|
| Authentication | scram-sha-256 (not md5 or trust) |
| SSL | Required for all connections (ssl = on, ssl_min_protocol_version = TLSv1.2) |
| Network | Listen only on private network interfaces |
| Firewall | Allow connections only from CaseBender application services |
| Superuser | Disable remote superuser access |
| Logging | Enable log_connections, log_disconnections, log_statement = 'ddl' |
| Password Policy | Minimum 16 characters, rotated quarterly |
pg_hba.conf Example:
# Reject all by default
host all all 0.0.0.0/0 reject
# Allow CaseBender services from private network only
hostssl casebender casebender_app 10.0.1.0/24 scram-sha-256
Backup Security
- Encrypt backups at rest (AES-256)
- Store backups in a separate location from the primary database
- Test backup restoration quarterly
- Retain backups according to your compliance requirements (minimum 30 days)
- Monitor backup job success/failure with alerting
Redis Security
Redis Hardening
| Setting | Recommendation |
|---|
| Authentication | requirepass with a strong password (32+ characters) |
| TLS | Enable TLS for all connections (tls-port instead of port) |
| Network | Bind to private network interface only (bind 10.0.1.x) |
| Dangerous Commands | Rename or disable FLUSHALL, FLUSHDB, CONFIG, DEBUG |
| Max Memory | Set maxmemory with maxmemory-policy allkeys-lru |
| Persistence | Enable AOF persistence for durability |
redis.conf Example:
bind 10.0.1.5
port 0
tls-port 6379
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
requirepass YOUR_STRONG_PASSWORD_HERE
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG "CONFIG_b4c2e8f1"
maxmemory 2gb
maxmemory-policy allkeys-lru
Container Security
Runtime Hardening
If deploying CaseBender with Docker or Kubernetes:
Docker Compose:
services:
web:
image: casebender/web:latest
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
tmpfs:
- /tmp
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '0.5'
memory: 1G
Kubernetes:
securityContext:
runAsNonRoot: true
runAsUser: 1001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "500m"
memory: "1Gi"
Image Verification
Before deploying, verify container image signatures:
# Verify image signature
cosign verify \
--certificate-identity-regexp="github.com/casebender" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
REGISTRY/casebender/web:TAG
# Verify SBOM attestation
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp="github.com/casebender" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
REGISTRY/casebender/web:TAG
Network Security
Firewall Rules
| Source | Destination | Port | Protocol | Purpose |
|---|
| Internet | Load Balancer | 443 | HTTPS | User access |
| Load Balancer | Web/API/Ingestion | 3000/4000/4100 | HTTP | Application traffic |
| App Services | PostgreSQL | 5432 | TCP/TLS | Database |
| App Services | Redis | 6379 | TCP/TLS | Cache/Queue |
| App Services | Elasticsearch | 9200 | HTTPS | Search |
| App Services | SIEM | Varies | TCP/TLS | Audit forwarding |
Recommendations
- Block all inbound traffic except port 443
- Use private networking for all inter-service communication
- Implement network segmentation between application and data tiers
- Enable network flow logging for forensic analysis
- Consider a Web Application Firewall (WAF) in front of the load balancer
Monitoring
Health Check Endpoints
CaseBender exposes health check endpoints for monitoring:
| Endpoint | Purpose | Response |
|---|
/api/health/liveness | Is the service running? | 200 OK / 503 |
/api/health/readiness | Is the service ready to accept traffic? | 200 OK / 503 |
/api/health/detailed | Detailed health with dependency status | JSON with component health |
Recommended Monitoring
| Metric | Alert Threshold | Tool |
|---|
| Health check failures | 3 consecutive failures | Prometheus, Datadog, CloudWatch |
| Response time (P95) | > 2 seconds | APM tool |
| Error rate (5xx) | > 1% of requests | Log aggregation |
| CPU utilization | > 80% sustained | Infrastructure monitoring |
| Memory utilization | > 85% | Infrastructure monitoring |
| Disk usage | > 80% | Infrastructure monitoring |
| Certificate expiry | < 30 days | Certificate monitoring |
| Backup age | > 24 hours | Backup monitoring |
Log Aggregation
Collect and centralize logs from all CaseBender services:
- Application logs (structured JSON)
- Access logs (reverse proxy)
- Database logs (PostgreSQL)
- Redis logs
- Container runtime logs
Use a log aggregation solution (ELK, Loki, Datadog, Splunk) to centralize, search, and alert on log data.
Backup and Recovery
Backup Strategy
| Component | Frequency | Retention | Method |
|---|
| PostgreSQL | Daily (full) + Continuous (WAL) | 30 days | pg_dump + WAL archiving |
| Redis | Hourly (AOF) | 7 days | AOF persistence + snapshots |
| Elasticsearch | Daily | 14 days | Snapshot and restore |
| Configuration | On change | 90 days | Version control |
Recovery Targets
| Metric | Target | Description |
|---|
| RPO (Recovery Point Objective) | < 1 hour | Maximum acceptable data loss |
| RTO (Recovery Time Objective) | < 4 hours | Maximum acceptable downtime |
Recovery Testing
- Test database restoration quarterly
- Test full environment recovery annually
- Document recovery procedures and keep them updated
- Conduct tabletop exercises for disaster scenarios