SOC 2 Type II — Evidence Map & Readiness Tracker
Owner: Security + Eng. Review cadence: quarterly and pre-audit.
SOC 2 Type II is the anchor cert (see README → Compliance). Our technical
controls are strong; the gap is evidence + the operational/policy layer.
This tracker maps each Trust Services Criteria (TSC 2017, rev. 2022) common
criterion to where its evidence lives and what's still missing. It complements
the NIST 800-53 mapping in SECURITY.md (that doc is the
control narrative; this is the auditor-facing evidence index).
Legend: ✅ implemented + evidence exists · 🟡 implemented, evidence/policy
partial · ❌ not yet · 📋 process/org control (not code).
Policy index
The policies + procedures the rest of this tracker references, with owners and
review cadences. Each is committed in this repository.
Common Criteria
CC1 — Control Environment (governance)
| # |
Criterion |
Evidence / location |
Status |
| CC1.1 |
Integrity & ethics |
Code of Conduct, InfoSec policy. Employee handbook is the remaining org artifact. |
🟡 |
| CC1.2 |
Board oversight |
Org chart, board minutes |
📋 ❌ |
| CC1.3 |
Structure & authority |
RBAC (owner/admin/member), InfoSec policy § 2 (roles + responsibilities), CONTRIBUTING.md change-mgmt |
✅ |
| CC1.4 |
Competence |
Security training (on-hire ≤ 14d + annual refresher + curriculum + completion records); hiring records remain as the org artifact |
🟡 (cadence kicks in after first sessions logged) |
| CC1.5 |
Accountability |
InfoSec policy § 5 (onboarding/offboarding + quarterly access review), GET /cp/access-review snapshot |
🟡 (cadence kicks in after first onboarding/offboarding cycle is logged) |
CC2 — Communication & Information
| # |
Criterion |
Evidence / location |
Status |
| CC2.1 |
Internal data quality |
Audit logs (cp_audit_events + /v1/audit billing-ops — both WORM hash-chained with a …/verify endpoint — see audit-trail architecture); per-period ledger seals (SHA-256 digest stored at month-end close, GET /v1/ledger/:id/seals/verify) for SOC 1 ICFR ledger immutability; structured logging |
✅ |
| CC2.2 |
Internal comms of responsibilities |
InfoSec policy, this repo's SECURITY.md + CONTRIBUTING.md |
✅ |
| CC2.3 |
External comms |
Vulnerability Disclosure Policy, /.well-known/security.txt, public Trust Center at /trust |
✅ |
CC3 — Risk Assessment
| # |
Criterion |
Evidence / location |
Status |
| CC3.1 |
Objectives + risk identification |
This tracker, README roadmap, risk register (quarterly cadence) |
✅ |
| CC3.2 |
Risk identification |
Risk register, threat model |
📋 ❌ |
| CC3.3 |
Fraud risk |
— |
📋 ❌ |
| CC3.4 |
Change risk |
CHANGELOG + branch protection + CI gates |
🟡 |
CC4 — Monitoring
| # |
Criterion |
Evidence / location |
Status |
| CC4.1 |
Ongoing/separate evals |
Pentest program (vendor selection + RoE + expected deliverables + retest + 7-year report retention + annual review), bug bounty program (private invite → public, reward tiers, eligibility, duplicate handling), CI security scan, Trivy → Security tab |
🟡 (cadence kicks in after first pentest engagement + first bounty program phase logged) |
| CC4.2 |
Deficiency comms |
Remediation SLA (SECURITY.md), Dependabot alerts |
✅ |
CC5 — Control Activities
| # |
Criterion |
Evidence / location |
Status |
| CC5.1–5.3 |
Control selection/deployment via policy + tech |
NIST mapping (SECURITY.md), PodSecurityStandards + NetworkPolicies in the chart |
🟡 |
CC6 — Logical & Physical Access
| # |
Criterion |
Evidence / location |
Status |
| CC6.1 |
Logical access controls |
middleware/{authenticate,require-admin}, OIDC SSO, sessions, MFA (TOTP) |
✅ |
| CC6.2 |
Registration/auth |
Signup + invite flow, email/phone verification; quarterly access-review snapshot at GET /cp/access-review (JSON + CSV) |
✅ |
| CC6.3 |
Access removal |
Org-delete purges users/memberships + revokes sessions; role update/remove; GET /cp/access-review flags stale members the admin should remove |
✅ |
| CC6.4 |
Physical access |
Cloud/on-prem operator's data-center controls |
📋 ❌ |
| CC6.5 |
Data disposal |
Data retention policy (TTL per class + enforcement path) + GET /cp/retention machine-readable table; audit-retention sweeper enforces; DSAR-erase anonymizes customer PII per Art. 17(3)(b) |
✅ |
| CC6.6 |
Boundary protection |
Security headers + strict CSP, NetworkPolicies (cross-tenant isolation), TLS at ingress |
🟡 |
| CC6.7 |
Data in transit/movement |
TLS 1.x at ingress (HSTS set; TLS terminated by operator), in-cluster-only data |
🟡 |
| CC6.8 |
Malicious software |
Trivy scan, Dependabot, restricted PodSecurityStandards, read-only rootfs |
✅ |
CC7 — System Operations
| # |
Criterion |
Evidence / location |
Status |
| CC7.1 |
Vulnerability detection |
Security-scan CI (npm audit + Trivy + SBOM), Dependabot |
✅ |
| CC7.2 |
Monitoring for anomalies |
Audit log of mutating /cp/* incl. failures, CSP violation reports (csp.violation), rolled-up org-scoped security alerts (/cp/security-alerts), outbound email + webhook fan-out on first cross to high severity (/cp/security-alerts/notifications); both audit logs are off-host-exportable as NDJSON (/cp/audit/export, /v1/audit/export) for SIEM ingestion |
✅ |
| CC7.3 |
Incident evaluation |
Incident response plan — severity tiers, triage flow, decision tree |
✅ |
| CC7.4 |
Incident response |
Incident response plan — roles, on-call rotation + escalation, comms templates, post-mortem template, quarterly tabletop cadence |
🟡 (cadence kicks in once first tabletop runs) |
| CC7.5 |
Recovery |
Reclaim backups + DR restore drill procedure (quarterly cadence, automated phases A–D via npm run dr:drill) |
🟡 (cadence kicks in once first drill logged under docs/compliance/dr-drills/) |
CC8 — Change Management
| # |
Criterion |
Evidence / location |
Status |
| CC8.1 |
Change authorization & testing |
PR review + branch protection (CONTRIBUTING.md), CHANGELOG gate, CI (lint/test/scan), image build pipeline |
🟡 (branch protection must be enabled on main) |
CC9 — Risk Mitigation
| # |
Criterion |
Evidence / location |
Status |
| CC9.1 |
Risk mitigation activities |
Data-locality (in-cluster only), per-tenant isolation, least-privilege Postgres RBAC, BCP/DR policy (scenario catalog + vendor continuity) |
✅ |
| CC9.2 |
Vendor/subprocessor mgmt |
Vendor management policy (intake gate, security review checklist, annual review, offboarding), public subprocessor list |
🟡 (per-subprocessor DPAs are the remaining org-work) |
Availability (A1) — relevant for a billing SaaS
| # |
Criterion |
Evidence / location |
Status |
| A1.1 |
Capacity |
Resource requests/limits in the chart; per-(org,env) pods; BCP/DR policy § 3 business-level RTOs |
🟡 |
| A1.2 |
Environmental protections / backup |
Bundled Postgres/Redis PVCs, reclaim backups on a PV, encrypted off-cluster backup mirror with optional KMS-wrapped DEK, BCP/DR policy § 5 risk scenarios |
🟡 (encryption-at-rest now operator-configurable — every PVC, incl. provisioned data-plane, takes a storageClass knob to point at a KMS-encrypted class; DR drill + BCP policy in place) |
| A1.3 |
Recovery testing |
DR restore drill procedure + npm run dr:drill helper for phases A–D; BCP/DR policy § 10 drill cadence; per-quarter drill log under docs/compliance/dr-drills/ |
🟡 (cadence kicks in once first drill logged) |
Top evidence gaps to close (ranked)
Split by what unblocks each one — a code / config change vs a calendar entry
vs an executed contract. Auditor-facing prioritization should track the same
split.
Blocked on cluster / secrets / cert / DR / FIPS infra
- Encryption at rest (A1.2 / CC6.1) — the Helm + provisioner wiring now
ships: every PVC (control-plane backups, bundled Postgres/Redis, and each
provisioned per-(org,env) data-plane volume) takes an optional
storageClass
so an operator can point them at a KMS-encrypted class. Remaining is the
operator choosing/providing that class (a deployment-config + cloud-KMS
decision), plus FIPS-validated crypto — see the README roadmap entry.
- Branch protection on
main (CC8.1) — GitHub organization-settings
change; settings documented in CONTRIBUTING.md.
Blocked on first cadence run (calendar)
- First tabletop exercise (CC7.4) — the incident response plan
is in place; the cadence becomes evidence after the first quarterly run is
logged under
docs/compliance/tabletops/.
- First DR drill run (CC7.5 / A1.3) — procedure +
npm run dr:drill
helper + log template are in place; cadence becomes evidence after the
first run is logged under docs/compliance/dr-drills/.
- First training cycle logged (CC1.4) — curriculum + records format are
in security-training.md; cadence becomes
evidence after the first on-hire + annual sessions are logged in the
personnel files.
- Onboarding / offboarding records (CC1.5 / CC6.3) — the
access-review snapshot (
GET /cp/access-review) is the recurring artifact;
evidence kicks in once the first onboarding + offboarding cycle is logged.
Blocked on executed contracts / org work
- Subprocessor DPAs (CC9.2) — the public subprocessor list +
vendor management policy intake gate are
live; executing the per-subprocessor DPAs is the remaining org work.
- Policy set — final org artifacts — InfoSec, IR, DR drill, BCP/DR, data
retention, vendor management, risk register, Code of Conduct, and security
training curriculum are all in this repo. Employee handbook + board
minutes remain as org artifacts outside this repo (CC1.1 / CC1.2).
- First pentest engagement + bug-bounty phase 1 (CC4.1) — program
structure + vendor selection criteria + reward tiers documented in
penetration-testing.md and
bug-bounty-program.md; evidence is the first
delivered engagement + the first private-invite bounty phase log.
The ✅/🟡 rows are largely satisfied by this codebase; the ❌/📋 rows above
are split between code changes (we can do), scheduled events (we have to run
the calendar), and contracted work (counterparty has to sign).