This directory holds artifacts from periodic security scans against the Loopless stack.
ZAP baseline is a passive scan: no exploitation, no auth-bypass attempts. Safe to run against any environment.
# Start the full stack
docker compose --profile core --profile observability up -d
# Wait for backend health
until curl -sf http://localhost:8081/health/ready; do sleep 2; done
# Run ZAP against the API
docker run --rm --network host \
-v "$(pwd)/devops/security:/zap/wrk" \
-t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
-t http://localhost:8081 \
-r zap-baseline-report.html \
-J zap-baseline-report.json \
-w zap-baseline-warnings.md \
-m 5 \
-a
# Run ZAP against the frontend (proxy via nginx)
docker run --rm --network host \
-v "$(pwd)/devops/security:/zap/wrk" \
-t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
-t http://localhost \
-r zap-frontend-report.html \
-J zap-frontend-report.json \
-m 5 \
-aReports land in devops/security/. Commit them after triaging findings.
- Open
zap-baseline-report.htmlin a browser - For each High/Medium finding:
- Verify it is reachable on the listed endpoint
- Open a
fix/security-XXXXbranch with the patch - Update
docs/security-audit.mdwith the finding + resolution
- Re-run the scan after fixes land
Weekly cron via .github/workflows/security-scan.yml:
- Runs every Monday 03:00 UTC
- Spins up the compose stack
- Runs ZAP baseline
- Uploads report as workflow artifact
- Opens an issue if
WARN-NEWorFAIL-NEWcount >0
- ZAP active scan (
zap-full-scan.py) is more aggressive and may trigger rate limiting. Do not run against production without prior coordination. - Findings are scored against OWASP Top 10 2021.
- Baseline reports are committed (no secrets in scan output); active reports are gitignored.