OWASP ZAP (Zed Attack Proxy) is the world's most widely used open-source web security scanner. Security teams and CI/CD pipelines rely on ZAP to find vulnerabilities before attackers do — but ZAP itself, especially when running as a daemon in automated pipelines, can silently stop working. When that happens, your security gate stops enforcing policies with no visible error.
In this tutorial you'll set up end-to-end monitoring for OWASP ZAP using Vigilmon — free tier, no credit card.
Why OWASP ZAP needs dedicated monitoring
ZAP in daemon mode has failure patterns that go unnoticed until a scan job runs:
- Daemon startup failure — ZAP's daemon silently fails to bind its API port on startup, meaning subsequent scan jobs connect to nothing and fail with cryptic timeout errors
- API key mismatches — the ZAP API requires an API key by default; a configuration change can lock out automated scanners without any obvious sign the daemon is still up
- Memory exhaustion during scans — active scans on large targets consume significant heap; an OOM crash leaves the daemon dead while the orchestration layer still expects it to be responsive
- Stale or skipped scan jobs — CI pipeline configuration drift means ZAP scans stop being triggered, but the security dashboard still shows last week's green result
Monitoring ZAP's API port and using heartbeats for scheduled scan jobs catches these issues before a vulnerability slips through an unchecked pipeline.
What you'll need
- OWASP ZAP running in daemon mode (see below)
- Network access from Vigilmon to your ZAP host
- A free Vigilmon account (sign up takes 30 seconds)
Step 1: Start ZAP in daemon mode
If you're running ZAP as a persistent service (common for CI/CD integration), start it in headless daemon mode:
# Start ZAP daemon on default port 8080
zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.addrs.addr.name=.* -config api.addrs.addr.regex=true -config api.key=your-api-key
Or with Docker:
docker run -d --name zap \
-p 8080:8080 \
ghcr.io/zaproxy/zaproxy:stable \
zap.sh -daemon \
-host 0.0.0.0 \
-port 8080 \
-config api.addrs.addr.name=.* \
-config api.addrs.addr.regex=true \
-config api.key=your-api-key
For a systemd service file:
[Unit]
Description=OWASP ZAP Security Scanner Daemon
After=network.target
[Service]
Type=simple
User=zap
ExecStart=/opt/zaproxy/zap.sh -daemon -host 0.0.0.0 -port 8080 -config api.key=your-api-key
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Step 2: Verify the ZAP API health endpoint
ZAP exposes a JSON API you can use as a health check target:
GET http://your-zap-host:8080/JSON/core/view/version/?apikey=your-api-key
Expected response:
{
"version": "2.14.0"
}
Test it from your terminal:
curl "http://your-zap-host:8080/JSON/core/view/version/?apikey=your-api-key"
If ZAP returns the version JSON, the daemon is alive and the API is responding. A timeout or connection refused means the daemon is down.
Step 3: Set up HTTP monitoring for the ZAP API
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS as the type
- Set the URL to:
http://your-zap-host:8080/JSON/core/view/version/?apikey=your-api-key - Set the check interval to 1 minute
- Under Expected response:
- Status code:
200 - Response body contains:
"version"
- Status code:
- Save the monitor
Vigilmon now probes the ZAP API every minute. If ZAP crashes or stops responding, an incident fires immediately.
Security note: If your ZAP daemon is publicly accessible, ensure the API key is set and the ZAP host is behind a firewall or VPN. Never expose ZAP's API port to the open internet without authentication.
Step 4: Add TCP port monitoring
A TCP port check verifies that ZAP's listener is bound at the OS level, independent of whether the API responds correctly:
- Monitors → New Monitor → TCP Port
- Hostname:
your-zap-host - Port:
8080(or your configured ZAP port) - Save the monitor
This catches cases where the ZAP process dies but the port entry lingers in a TIME_WAIT state, or where the process is stuck and not accepting new connections.
Step 5: Set up heartbeat monitoring for scheduled ZAP scan jobs
The most common ZAP failure mode in CI/CD is not a crashed daemon — it's a scan job that silently stops being triggered. Heartbeat monitoring catches this.
How it works: Vigilmon gives you a ping URL. Your CI pipeline hits that URL after each successful ZAP scan. If the ping doesn't arrive within the expected window, Vigilmon alerts you.
- In Vigilmon, go to Monitors → New Monitor → Heartbeat
- Name it (e.g.,
ZAP nightly baseline scan) - Set the expected interval (e.g., 24 hours for a daily scan)
- Set a grace period (e.g., 1 hour) to accommodate variable scan durations
- Copy the ping URL
Add the ping to your CI pipeline. Example for a GitHub Actions workflow:
security-scan:
name: OWASP ZAP Baseline Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'https://your-app.example.com'
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a'
- name: Ping Vigilmon heartbeat
if: success()
run: curl -s "https://vigilmon.online/ping/your-heartbeat-token"
For a shell script wrapping a ZAP Docker scan:
#!/bin/bash
docker run --rm \
ghcr.io/zaproxy/zaproxy:stable \
zap-baseline.py \
-t https://your-app.example.com \
-J zap-report.json
if [ $? -eq 0 ]; then
curl -s "https://vigilmon.online/ping/your-heartbeat-token" > /dev/null
echo "ZAP scan complete — heartbeat sent"
else
echo "ZAP scan failed — heartbeat not sent, Vigilmon will alert"
exit 1
fi
If the CI runner goes offline, the scan job gets misconfigured, or the ZAP target becomes unreachable in a way that causes the scan to fail, Vigilmon fires an alert within your grace period.
Step 6: Enable SSL certificate monitoring
If you proxy ZAP behind HTTPS (common for CI environments that use Nginx or Caddy as a TLS terminator in front of ZAP), Vigilmon automatically checks the SSL certificate expiry for any HTTPS monitor you create.
- Update your ZAP HTTP monitor URL to use
https://if you have TLS in front of ZAP - Open that monitor in Vigilmon and go to the SSL tab
- Set the Alert before expiry threshold (e.g., 30 days)
Vigilmon will alert you before the certificate lapses — before automated scan jobs start failing with TLS errors.
Summary: Vigilmon monitors for OWASP ZAP
| Monitor | Type | What it catches |
|---------|------|-----------------|
| /JSON/core/view/version/ | HTTP | ZAP daemon crash, API unresponsive |
| zap-host:8080 | TCP | Port binding failure, process death |
| Nightly baseline scan | Heartbeat | Scheduled scan stopped running in CI |
| SSL certificate | SSL | TLS cert expiry before scans break |
What's next
- Alert channels — connect Vigilmon to Slack or PagerDuty so your security team gets notified the moment ZAP goes down, not when a developer notices CI is producing outdated reports
- Status page — create a Vigilmon status page grouping your ZAP daemon and your application monitors so stakeholders can see security tooling health at a glance
- Multiple ZAP targets — if you run separate ZAP instances per environment (staging, pre-prod), create one heartbeat monitor per scan job so coverage gaps are caught environment by environment
Get started free at vigilmon.online — no credit card, monitors start running in under a minute.