Continuous Monitoring
zGovern's continuous monitoring engine automatically scans your connected integrations every 6 hours, surfaces compliance failures in real time, and keeps your risk register up to date without manual intervention.
How Continuous Monitoring Works
When you connect an integration (e.g., AWS, GitHub, Okta), zGovern schedules recurring automated checks using node-cron. Each check inspects a specific configuration or security control — for example, whether S3 bucket logging is enabled or whether all Okta users have MFA enrolled.
Check results are stored as IntegrationCheck records and are immediately visible in the Monitoring page. The results feed into:
- The Compliance Score shown on the Dashboard (cached for up to 7 hours)
- The Risk Register (auto-creates risks for FAIL + HIGH severity checks)
- The Audit Workspace (auto-evidence tagged
[Auto]) - Email alerts to ADMIN users for newly failing checks
Scan Schedule
| Job | Schedule | Cron Expression | Description |
|---|---|---|---|
| Full integration scan | Every 6 hours | 0 */6 * * * |
Runs all checks for all active integrations across all organizations |
| Weekly digest | Monday, 8:00 AM | 0 8 * * 1 |
Sends a summary email to all ADMIN users with pass/fail counts and trend direction |
POST /api/monitoring/run-now. This is useful after fixing a compliance issue to verify resolution without waiting up to 6 hours.
Check Statuses
Each automated check produces one of four status values:
| Status | Meaning | Action Required? |
|---|---|---|
| PASS | The control is properly configured and compliant | No — monitor for regressions |
| FAIL | The control is misconfigured or non-compliant | Yes — a risk is auto-created; remediate immediately |
| WARNING | The control is partially compliant or a best practice is not followed | Recommended — review and assess risk |
| INFO | Informational data collected — no compliance judgment | No — for context only |
Trend Analysis
The Trend Analysis tab in the Monitoring page shows a sparkline table for each check, displaying its status history across the last 10 scan runs. This lets you quickly identify:
- Flapping checks — oscillating between PASS and FAIL (indicates intermittent issues)
- Improving checks — recently moved to PASS after remediation
- Degrading checks — recently moved from PASS to FAIL
- Stable passing checks — consistently green (high confidence)
The API returns trend data with a direction indicator:
{
"success": true,
"data": [
{
"checkName": "AWS IAM MFA Enforcement",
"integration": "AWS Production",
"latestStatus": "PASS",
"trend": "improving",
"sparkline": ["FAIL", "FAIL", "FAIL", "PASS", "PASS", "PASS", "PASS", "PASS", "PASS", "PASS"]
},
{
"checkName": "GitHub Branch Protection",
"integration": "GitHub Org",
"latestStatus": "FAIL",
"trend": "degrading",
"sparkline": ["PASS", "PASS", "PASS", "PASS", "PASS", "PASS", "PASS", "FAIL", "FAIL", "FAIL"]
}
]
}
Auto-Risk Creation
When a check transitions to FAIL status with a HIGH or CRITICAL severity, zGovern automatically creates a risk entry in the Risk Register. This ensures no compliance failure goes untracked.
| Check Severity | Auto-Risk Created? | Risk Severity |
|---|---|---|
| CRITICAL | Yes | CRITICAL |
| HIGH | Yes | HIGH |
| MEDIUM | No (manual) | — |
| LOW | No (manual) | — |
The auto-created risk includes:
title: derived from the check name (e.g., "AWS S3 Public Bucket Exposure")description: the check's failure detail messagesourceCheckId: foreign key linking back to theIntegrationCheckrecordlikelihoodandimpact: set based on the check's predefined values
Alert Deduplication
zGovern tracks which checks were already failing in the previous scan run. Email alerts are only sent for newly failing checks — checks that were PASS in the last run and are now FAIL. This prevents alert fatigue from repeated notifications about the same known issue.
Risk Re-open Behavior
When a risk is marked RESOLVED or CLOSED but its linked source check subsequently fails again, zGovern automatically:
- Reopens the risk (sets status back to OPEN)
- Increments the
reopenCountfield - Updates
lastReopenedAtto the current timestamp - Sends an email alert noting the risk has been reopened
This behavior is visible in the Risk Register — risks with a non-zero reopenCount display a badge indicating how many times they have been reopened.
Email Alerts
zGovern can send email notifications using any SMTP provider. Configure the following environment variables in docker-compose.yml:
| Variable | Required | Description |
|---|---|---|
SMTP_HOST |
Yes (for email) | SMTP server hostname (e.g., smtp.sendgrid.net) |
SMTP_PORT |
Yes (for email) | SMTP port — typically 587 (TLS) or 465 (SSL) |
SMTP_USER |
Yes (for email) | SMTP authentication username |
SMTP_PASS |
Yes (for email) | SMTP authentication password or API key |
SMTP_FROM |
Yes (for email) | From address (e.g., alerts@zgovern.com) |
APP_URL |
Recommended | Public URL of your app — used in email links (e.g., https://app.example.com) |
SMTP_HOST is not set, all emails are logged to the backend console in the format they would be sent. This is useful for development and testing.
Email Types
| Recipients | Trigger | |
|---|---|---|
| New scan failure alert | All ADMIN users | A check transitions from PASS → FAIL |
| Risk reopened alert | All ADMIN users + risk owner | A resolved/closed risk is reopened by a failing check |
| Password reset | The requesting user | POST /api/auth/forgot-password |
| Weekly digest | All ADMIN users | Every Monday at 8:00 AM |
Manual Scan API
Trigger an immediate scan programmatically:
curl -X POST https://app.zgovern.com/api/monitoring/run-now \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json"
{
"success": true,
"message": "Monitoring scan started",
"data": {
"jobId": "scan_1709900400000",
"integrationsQueued": 3
}
}