Security Best Practices and Compliance
LEVEL 0
The Problem
You’ve learned individual security techniques:
- Scanning images
- Running as non-root
- Secrets management
- Network isolation
But how do you tie it all together? How do you ensure your team follows these practices? How do you prove compliance with security standards (SOC 2, PCI-DSS, HIPAA)?
You need a security framework and automation.
LEVEL 1
The Concept — The Checklist System
The Concept
Imagine airline pilots before takeoff.
They don’t rely on memory. They use checklists:
- ✓ Fuel levels checked
- ✓ Flight controls tested
- ✓ Weather reviewed
- ✓ Emergency equipment verified
Security checklists prevent human error.
For containers:
- ✓ Image scanned for vulnerabilities
- ✓ Running as non-root
- ✓ Secrets not hardcoded
- ✓ Resource limits set
- ✓ Network isolation configured
- ✓ Logs collected
LEVEL 2
The Mechanics — Security Checklist
The Mechanics
Image Security:
- Use official or verified base images
- Scan images for vulnerabilities
- Keep base images updated
- Use minimal base images (Alpine, distroless)
- Multi-stage builds to remove build tools
- No secrets in images
- Sign images with Docker Content Trust
Runtime Security:
- Run as non-root user
- Drop all capabilities, add only needed ones
- Use read-only root filesystem where possible
- Set
no-new-privileges - Resource limits (CPU, memory, PIDs)
- No
--privilegedmode
Secrets Management:
- No hardcoded secrets in Dockerfiles
- No secrets in environment variables visible in
docker inspect - Use secrets management system (Docker Secrets, Vault, etc.)
- Rotate secrets regularly
- Different secrets per environment
Network Security:
- Network segmentation (separate networks for different tiers)
- Minimal port exposure
- TLS for inter-service communication
- No containers on host network mode
Logging and Monitoring:
- Centralized logging
- Log retention policy
- Security event monitoring
- Intrusion detection
Compliance:
- Regular security audits
- Vulnerability scanning in CI/CD
- Access controls documented
- Incident response plan
LEVEL 3
Automating Security with Policy Engines
Open Policy Agent (OPA):
Define policies as code:
# policy.rego
package docker.security
# Deny images not from trusted registries
deny[msg] {
input.image
not startswith(input.image, "myregistry.com/")
not startswith(input.image, "docker.io/library/")
msg = "Image must be from trusted registry"
}
# Deny containers running as root
deny[msg] {
input.user == "root"
msg = "Container must not run as root"
}
# Require resource limits
deny[msg] {
not input.memory_limit
msg = "Memory limit must be set"
}
Enforce in CI/CD:
opa eval --data policy.rego --input image-config.json "data.docker.security.deny"
Falco (Runtime Security):
Detects anomalous behavior:
# falco_rules.yaml
- rule: Unexpected outbound connection
desc: Detect unexpected outbound connections from containers
condition: >
container and
outbound and
not allowed_outbound_destinations
output: "Unexpected outbound connection (image=%container.image.repository)"
priority: WARNING
LEVEL 4
Compliance Standards
CIS Docker Benchmark:
Industry-standard security configuration guide:
- Host Configuration (1-7)
- Docker Daemon Configuration (1-18)
- Docker Daemon Files (1-6)
- Container Images (1-8)
- Container Runtime (1-31)
Use automated scanners:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/docker-bench-security
PCI-DSS (Payment Card Industry):
Requirements for handling credit card data:
- Network segmentation
- Encryption at rest and in transit
- Access controls
- Logging and monitoring
- Regular vulnerability scans
HIPAA (Healthcare):
Requirements for handling medical data:
- Encryption
- Access controls
- Audit logs
- Disaster recovery
SOC 2:
Requirements for service providers:
- Security policies documented
- Access controls
- Change management
- Incident response
- Monitoring
LEVEL 5
Security Scanning in CI/CD
Complete security pipeline:
# .github/workflows/security.yml
name: Security Scan
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
# Scan Dockerfile for misconfigurations
- name: Scan Dockerfile
run: |
docker run --rm -v $(pwd):/project \
hadolint/hadolint hadolint /project/Dockerfile
# Build image
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
# Scan for vulnerabilities
- name: Scan image
run: |
trivy image --severity HIGH,CRITICAL \
--exit-code 1 myapp:${{ github.sha }}
# Scan for secrets
- name: Scan for secrets
run: |
trivy image --security-checks secret \
--exit-code 1 myapp:${{ github.sha }}
# Check security policies
- name: Check policies
run: |
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/docker-bench-security
# Push only if all checks pass
- name: Push image
if: success()
run: docker push myapp:${{ github.sha }}
Continuous monitoring:
# Schedule daily scans
on:
schedule:
- cron: '0 2 * * *' # 2 AM daily
jobs:
scan-production:
runs-on: ubuntu-latest
steps:
- name: Scan production images
run: |
for image in $(docker images --format "{{.Repository}}:{{.Tag}}"); do
trivy image --severity HIGH,CRITICAL $image
done