Controls catalogue
The catalogue is the source of truth for what the evidence module collects. Each control has a code (mapped to the SOC 2 Common Criteria), a topic, a cadence (daily / weekly / monthly / quarterly), and a Python check function that produces the evidence record.

The nine controls
| Code | Topic | Cadence | Pass criterion |
|---|---|---|---|
| CC6.1-MFA | MFA enforced on staff | Daily | 100% of internal users have totp_enabled=True |
| CC6.2-ACCESS | Quarterly access review freshness | Monthly | Last review ≤ 90 days; documented sign-off |
| CC6.3-2P | Segregation of duties (two-person rule) | Quarterly | Rule count ≥ baseline; 0 violations in period |
| CC7.1-VULN | Vulnerability scanning | Weekly | Last OpenVAS scan ≤ 7 days; 0 critical unpatched |
| CC7.3-IR | Incident response capability | Monthly | IRP version current; tabletop in last 12 months |
| CC8.1-CHANGE | Change management log | Monthly | All prod deploys have approved change tickets |
| CC1.4-TRAIN | Annual security + privacy training | Monthly | 100% staff trained in last 12 months |
| A1.2-BACKUP | Backup execution + integrity | Daily | Last backup ≤ 24h; last verified restore ≤ 90 days |
| C1.1-RETN | Data retention policy in force | Quarterly | Retention cron ran in last 7 days; queue reviewed |
Each control's record shape
Every check function returns a Python dict with this shape. The cron persists it as mfi.soc2.evidence.
{
'control_code': 'CC6.1-MFA',
'collected_at': '2026-06-13T08:00:00Z',
'cadence': 'daily',
'pass': True,
'summary': '7/7 internal users have MFA (100.0%)',
'details': {
'total_internal_users': 7,
'mfa_enabled': 7,
'mfa_percent': 100.0,
'policy_threshold_pct': 95.0,
'missing_users': [],
}
}
Reference
Trust Service Criteria coverage
| TSC | Coverage by shipped controls | Gap |
|---|---|---|
| Common Criteria (CC1-CC9) | CC1.4, CC6.1, CC6.2, CC6.3, CC7.1, CC7.3, CC8.1 | CC2 (governance), CC3-CC5 (objectives, info, monitoring), CC9 (vendor mgmt) — add custom |
| Availability (A1) | A1.2 (backup) | A1.1 (capacity) — add custom; A1.3 (recovery) — derive from A1.2 |
| Confidentiality (C1) | C1.1 (retention) | C1.2 (disposal) — manual |
| Processing Integrity (PI) | (not in scope by default) | All — add as custom if claimed |
| Privacy (P) | (not in scope by default — KDPA covers EU-equivalent) | All — add as custom if claimed |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Control shows 'failed' but the underlying state is fine | Check function has a bug or pass-threshold mis-set | Open the control → Edit → Pass threshold; run check manually; review details JSON for the false negative. |
| New control added but it never runs | Cron not picking it up — cadence field empty | Set cadence on the control record; restart the soc2-evidence cron worker. |
| Auditor asks for evidence of a control not in the catalogue | Custom criterion claimed in audit scope | Add a custom control (see Custom controls page); back-date check function if data exists. |
| Two controls have overlapping evidence | Same data point checked by two controls | By design — auditors love redundancy. Keep both unless one is clearly subsumed. |
See also
Was this page helpful?

