Skip to content

Continuous Controls Monitoring

Continuous Controls Monitoring (CCM) is the platform's always-on layer: instead of finding out at audit time that an evidence pipeline broke in March, scheduled jobs check health, trigger due control tests, flag overdue policy reviews, and chase overdue PBC requests, stale findings, and outstanding training every day.

How it runs

CCM is built on APScheduler with a persistent Postgres jobstore — jobs survive backend restarts. The jobstore URL is derived automatically from DATABASE_URL (converted to a synchronous psycopg URL), so no extra configuration is needed. If the scheduler fails to start, the backend logs a loud ERROR with a traceback (the app stays up) — it never fails silently.

Default jobs

Seven jobs are seeded idempotently at startup (they are created once and never duplicated; their metadata lives in the sgrc_scheduler_job_metadata table) — six daily CCM cron sweeps plus one high-frequency delivery retry:

Job Schedule (UTC) What it does
Daily evidence-source health & drift check 0 5 * * * Health-checks every configured data-source connection so broken evidence pipelines surface within 24 hours instead of at audit time.
Daily control-test schedule sweep 30 5 * * * Triggers control tests whose ControlSchedule.next_run_at has come due (max 10 per sweep) and kicks off background execution of the created assessments — the same execution path as a manual run.
Daily policy-review-due sweep 0 6 * * * Read-only sweep flagging policy documents whose review_due_date has passed.
Daily PBC due/overdue reminder sweep 15 6 * * * In-app reminders for PBC evidence requests due within 3 days or overdue, addressed to the request owner when their email matches a user (org-wide otherwise). Deduped per request per day.
Daily stale needs-review reminder sweep 45 6 * * * Org-wide reminders for findings stuck in needs_review for more than 7 days. Deduped per finding per day.
Daily training due/overdue reminder sweep 0 7 * * * Personal reminders for security-awareness training assignments due within 3 days or overdue and not yet completed.
A2A notification delivery sweep every 60 s (interval, not daily) Retries pending/failed A2A notification deliveries (webhook/email) with exponential backoff, including deliveries whose in-process attempt died with the process.

Control schedules themselves are managed from the Calendar page (/orgs/{org_id}/schedule API); the Dashboard surfaces schedules that are overdue, in grace, or due soon.

Job types

The scheduler supports thirteen job types in total: assessment, health_check, evidence_collection, policy_sync, report_generation, kri_collection, incident_monitoring, control_schedule_sweep, policy_review_sweep, pbc_reminder_sweep, review_reminder_sweep, training_reminder_sweep, and a2a_notification_sweep. Each has a live handler, and the seven default jobs above are instances of seven of them.

Managing jobs (API)

POST   /api/v1/schedules                # create a scheduled job
GET    /api/v1/schedules                # list jobs
GET    /api/v1/schedules/status         # scheduler status
GET    /api/v1/schedules/{job_id}       # job detail
PUT    /api/v1/schedules/{job_id}       # update
DELETE /api/v1/schedules/{job_id}       # delete
POST   /api/v1/schedules/{job_id}/run   # run now
POST   /api/v1/schedules/{job_id}/pause
POST   /api/v1/schedules/{job_id}/resume
GET    /api/v1/schedules/{job_id}/history  # execution history

Schedules use cron expressions with an explicit timezone (the defaults run in UTC).

Honest results

Job runs record their real outcome. A failed sweep returns status: "failed" with the error; the health check reports each connection's actual state. Nothing is marked green because a job merely ran — only because the underlying check passed.