Protect your web applications with enterprise-grade WAF in under 5 minutes β eliminate false-positive risk during deployment and slash SOC2 audit prep time.
Developmi Enterprise Edition β’ Curated by Miguel Lozano β’ GitHub β’ Container Registry
- Overview
- Quick Start
- Architecture
- Configuration Guide
- Docker Deployment
- Testing & Validation
- Monitoring & Observability
- Security
- Changelog
- Contributing
- License
- Contact & Support
Problem: Deploying a web application firewall typically requires weeks of tuning, dedicated appliances, and specialized security expertise. Most WAF solutions block legitimate traffic on day one, disrupting your users and forcing you to disable protections you just deployed.
This project solves that. It packages Caddy β the web server that automatically provisions TLS β with Coraza WAF and the OWASP Core Rule Set into a single hardened container. The WAF defaults to DetectionOnly mode, giving you a safe observation window before enforcement. You get 290+ protection rules covering SQL injection, XSS, command injection, and the entire OWASP Top 10 β without blocking a single legitimate request until you're ready.
- Non-root execution: Runs as
caddyuser (UID 1337) β no root privileges - Supply chain security: Pinned versions, SHA256 verification of OWASP CRS rules, Cosign-signed images, SBOM attestations
- Multi-stage builds: Minimal attack surface, optimized layers
- Health monitoring: Process verification healthcheck at both image and compose level
- Structured logging: JSON logs for SIEM integration
- Coraza WAF v2.2.0: Modern, high-performance web application firewall engine
- OWASP CRS v4.23.0: Latest Core Rule Set with 290+ protection rules
- DetectionOnly by default: Prevents false positives in new deployments
- Audit logging: JSON audit logs to stdout for easy monitoring
- Rate limiting: Built-in rate limiting plugin for DDoS protection
- Optimized Alpine base: Small footprint (~45MB compressed)
- TLS by default: Automatic Let's Encrypt integration
- Multi-architecture: Supports linux/amd64 and linux/arm64
- Cloud-native: Perfect for Kubernetes, Docker Swarm, and standalone Docker
- Bare-metal ready: Systemd service file included for non-containerized deployments
- Docker 24.x+ and Docker Compose v2.x+
docker pull ghcr.io/miguel-devops/caddy-waf:v2.0.0cp .env.example .env
# Edit .env with your domain/backend/image valuescp Caddyfile.example Caddyfile
# Edit Caddyfile for your domain and upstreamsdocker build -t your-registry/your-caddy-waf:custom \
--build-arg CORAZA_CADDY_REF=v2.2.0 \
--build-arg CADDY_RATELIMIT_REF=v0.1.0 \
--build-arg CADDY_DNS_CLOUDFLARE_REF=v0.2.3 \
.Then set CADDY_WAF_IMAGE=your-registry/your-caddy-waf:custom in .env.
{
order coraza_waf first
}
yourdomain.com {
respond "Caddy with Coraza WAF is running" 200
}docker compose up -dcaddy-waf/
βββ assets/ # Brand assets (logo)
βββ deploy/
β βββ systemd/ # Systemd service unit for bare-metal
βββ .github/workflows/ # CI/CD (build, scan, sign, push)
βββ Dockerfile # Multi-stage build with pinned plugins
βββ docker-compose.yml # Production-grade compose with security hardening
βββ Caddyfile # Runtime configuration (WAF + TLS + reverse proxy)
βββ Caddyfile.example # Templated configuration with 5 deployment examples
βββ .env.example # Environment variable template (3 groups)
βββ TUNING.md # WAF tuning guide per application type
βββ ROADMAP.md # Planned enhancements and compliance roadmap
βββ CHANGELOG.md # Version history (Keep a Changelog)
βββ CONTRIBUTING.md # Contribution guidelines
βββ SECURITY.md # Vulnerability disclosure policy
βββ LICENSE # MIT License
flowchart LR
Client[Client] -->|HTTPS :443| Caddy[Caddy v2.11]
Caddy -->|WAF layer| Coraza[Coraza WAF v2.2.0]
Coraza -->|OWASP CRS v4.23.0| Rules[290+ Rules]
Coraza -->|Decision| Action{Allow?}
Action -->|Yes| Backend[Upstream Backend]
Action -->|No| Block[Block + Audit Log]
Block -->|JSON| SIEM[SIEM / Log Aggregator]
Caddy -->|Auto TLS| LE[Let's Encrypt]
The WAF operates in three modes (configured in Caddyfile):
- DetectionOnly (Default): Logs attacks without blocking β perfect for initial deployment
- On: Active protection β blocks malicious requests
- Off: Disables WAF completely
Recommended rollout: Keep
SecRuleEngine DetectionOnlyfor a 7β14 day observation window. Review audit logs, tune CRS exclusions, then switch toSecRuleEngine Ononly after establishing a stable false-positive baseline.
{
email admin@example.com
order coraza_waf first
# JSON logging for observability
log {
output stdout
format json
}
}
(waf) {
coraza_waf {
directives `
Include /etc/caddy/coraza.conf
Include /etc/caddy/owasp-crs/crs-setup.conf
Include /etc/caddy/owasp-crs/rules/*.conf
# Start with DetectionOnly, change to On after tuning
SecRuleEngine DetectionOnly
# Audit logging
SecAuditEngine RelevantOnly
SecAuditLog /dev/stdout
SecAuditLogFormat JSON
`
}
}
# Your site configuration
example.com {
import waf
reverse_proxy backend:8080
}For detailed WAF tuning, rule exceptions, and performance optimization, see the complete TUNING GUIDE.
Project roadmap and planned security integrations are tracked in ROADMAP.md.
Mount your custom rules directory:
volumes:
- ./custom-crs:/etc/caddy/owasp-crs| Variable | Default | Description |
|---|---|---|
CADDY_WAF_IMAGE |
ghcr.io/miguel-devops/caddy-waf:v2.0.0 |
Caddy WAF image reference |
EXAMPLE_APP_IMAGE |
containous/whoami:latest |
Demo backend image |
SITE_ADDRESS |
localhost |
Site address/server name used by Caddy |
BACKEND_UPSTREAM |
example-app:80 |
Reverse proxy backend upstream |
ACME_EMAIL |
(empty) | Email for Let's Encrypt certificates |
CADDY_ADAPTER |
caddyfile |
Configuration adapter to use |
github.com/corazawaf/coraza-caddy/v2@v2.2.0β Coraza WAF integrationgithub.com/mholt/caddy-ratelimit@v0.1.0β Rate limiting (DDoS protection)github.com/caddy-dns/cloudflare@v0.2.3β Cloudflare DNS for ACME challenges
# Start with example backend
cp .env.example .env
cp Caddyfile.example Caddyfile
docker compose up -ddocker build \
--build-arg CORAZA_CADDY_REF=v2.2.0 \
--build-arg CADDY_RATELIMIT_REF=v0.1.0 \
--build-arg CADDY_DNS_CLOUDFLARE_REF=v0.2.3 \
-t caddy-waf:custom .sudo cp deploy/systemd/caddy-waf.service /etc/systemd/system/
sudo useradd -r -s /usr/sbin/nologin caddy-waf
sudo systemctl daemon-reload
sudo systemctl enable --now caddy-wafVerify the image signature before pulling in production:
cosign verify \
--certificate-identity "https://github.com/Miguel-DevOps/caddy-waf/.github/workflows/docker-build-scan-sign.yml@refs/heads/main" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
ghcr.io/miguel-devops/caddy-waf@sha256:<digest>Tip: Use immutable image digests (
@sha256:...) instead of version tags in production for deterministic deployments.
# Check container health
docker ps --filter "name=caddy-waf"
# View logs
docker logs caddy-waf
# Test WAF is working
curl -I https://yourdomain.com# Scan image with Trivy
docker run --rm aquasec/trivy image ghcr.io/miguel-devops/caddy-waf:v2.0.0
# Scan with Docker Scout
docker scout quickview ghcr.io/miguel-devops/caddy-waf:v2.0.0{
"level": "info",
"ts": 1678901234.567,
"logger": "http.log.access",
"msg": "handled request",
"request": {
"method": "GET",
"uri": "/test",
"proto": "HTTP/2",
"remote_ip": "192.168.1.100"
},
"waf_action": "detected",
"waf_rule_id": "941100"
}coraza_waf_processed_totalβ Total requests processedcoraza_waf_blocked_totalβ Requests blocked by WAFcoraza_waf_rules_triggeredβ Rules triggered (by ID)
This project follows a coordinated disclosure policy. If you discover a vulnerability, do not open a public issue. See SECURITY.md for:
- Supported versions
- Reporting instructions (GitHub Advisory + email)
- Response timelines (48h acknowledgment, 30-day fix target)
- Supply chain verification (Cosign + Trivy)
| Version | Supported |
|---|---|
| 2.0.x | β Yes |
| 1.0.x | β No |
See CHANGELOG.md for the full version history. The project follows Keep a Changelog and Semantic Versioning.
| Version | Date | Highlights |
|---|---|---|
| [Unreleased] | β | Cosign signing, Trivy scanning, audit improvements |
| 2.0.0 | 2026-03-14 | Security hardening, systemd, OCI labels, CI updates |
| 1.0.0 | 2026-02-09 | Initial release with Coraza WAF + OWASP CRS |
Contributions are welcome. Please read CONTRIBUTING.md before opening a pull request. This project follows Conventional Commits and the Developmi engineering standard.
- Report a bug or request a feature: GitHub Issues
- Advanced configuration: TUNING.md
- Roadmap: ROADMAP.md
For enterprise support, custom configurations, or security consulting:
- Website: developmi.com
- Email: miguel@developmi.com
- GitHub: Miguel-DevOps
Copyright Β© 2026 Miguel Lozano | Developmi. All rights reserved. Licensed under the MIT License.
- Caddy Server β Amazing web server with automatic HTTPS
- Coraza WAF β Enterprise-grade WAF engine
- OWASP Core Rule Set β Industry-standard protection rules
- Developmi β DevOps & Security consulting
Maintained by: Miguel Lozano | Developmi
- Role: Cloud & Infrastructure Engineer | FinOps & Bare Metal Specialist | AI Sovereignty Strategist under NIST/DORA Standards
- Philosophy: Security is not a feature; it is the baseline.
- Website: developmi.com
- GitHub: Miguel-DevOps
- LinkedIn: Miguel Lozano
Β© 2026 Miguel Lozano | Developmi. All rights reserved.