SOC 2 Compliance Templates
A complete SOC 2 Type II audit preparation package. Includes policy documents, control matrices mapped to all five Trust Service Criteria, evidence collection scripts, and audit checklists — built by practitioners who have been through the process.
Key Features
- Policy Document Templates — 12 foundational security policies (Information Security, Access Control, Incident Response, etc.) ready to customize.
- Control Matrix — Complete mapping to SOC 2 Trust Service Criteria with evidence requirements and testing procedures.
- Evidence Collection Automation — Python scripts that gather access reviews, change logs, and vulnerability scans.
- Audit Readiness Checklist — 150-point checklist organized by Trust Service Criteria with gap identification.
- Continuous Monitoring — Configuration templates for tracking control effectiveness between audits.
- Vendor Assessment Templates — Third-party vendor security questionnaires and risk classification.
- Gap Analysis Tool — Script comparing current controls against SOC 2 requirements with remediation plan.
Quick Start
# Extract the templates
unzip soc2-compliance-templates.zip
cd soc2-compliance-templates/
# Run the gap analysis against your current controls
python3 scripts/gap_analyzer.py --controls configs/current_controls.yaml --output gap_report.json
# Generate evidence collection tasks
python3 scripts/evidence_planner.py --audit-period "2026-01-01:2026-06-30" --output evidence_plan.md
# Validate policy documents
python3 scripts/policy_validator.py --policies policies/ --output validation.json
Control Matrix Schema
# controls/security_controls.yaml — SOC 2 Security Criteria Controls
controls:
- id: "CC6.1-01"
criteria: "CC6.1"
category: "Logical and Physical Access Controls"
title: "User Access Provisioning"
description: "New accounts provisioned via formal request/approval. Least privilege enforced."
owner: "IT Manager"
frequency: "Per occurrence"
evidence_type: "Access request tickets with approval chain"
test_procedure: "Sample 25 new accounts; verify documented approval before creation."
- id: "CC7.2-01"
criteria: "CC7.2"
title: "Security Event Monitoring"
description: "Real-time SIEM monitoring. Critical alerts trigger incident response."
owner: "SOC Team"
frequency: "Continuous"
evidence_type: "SIEM dashboards, alert logs, IR tickets"
Architecture / How It Works
Gap Analysis ──► Policy Development ──► Control Matrix ──► Evidence Collection
│ │
▼ ▼
Remediation Plan Audit Prep (150-point checklist)
│
▼
Auditor Fieldwork ──► Continuous Monitoring
Usage Examples
Evidence Collection Automation
import json
import logging
from datetime import datetime, timezone
from pathlib import Path
class EvidenceCollector:
"""Automated evidence collection for SOC 2 audit artifacts."""
def __init__(self, output_dir: str, audit_start: str, audit_end: str):
self.output_dir = Path(output_dir)
self.output_dir.mkdir(parents=True, exist_ok=True)
self.audit_start = datetime.fromisoformat(audit_start)
self.audit_end = datetime.fromisoformat(audit_end)
self.manifest: list[dict] = []
def collect_access_review(self, iam_export_path: str) -> dict:
"""CC6.1 — Collect access review evidence."""
source = Path(iam_export_path)
status = "collected" if source.exists() else "source_not_found"
evidence = {"control_id": "CC6.1-02", "collected_at": datetime.now(timezone.utc).isoformat(), "status": status}
if source.exists():
dest = self.output_dir / "CC6.1-02_access_review.json"
dest.write_text(source.read_text())
evidence["artifact_path"] = str(dest)
self.manifest.append(evidence)
return evidence
def collect_change_logs(self, changelog_dir: str) -> dict:
"""CC8.1 — Collect change management evidence within audit period."""
changes = [entry for f in Path(changelog_dir).glob("*.json")
for entry in json.load(open(f))
if self.audit_start <= datetime.fromisoformat(entry["date"]) <= self.audit_end]
out = self.output_dir / "CC8.1-01_changes.json"
out.write_text(json.dumps(changes, indent=2))
self.manifest.append({"control_id": "CC8.1-01", "changes": len(changes), "path": str(out)})
return {"changes_in_period": len(changes)}
def generate_manifest(self) -> None:
(self.output_dir / "evidence_manifest.json").write_text(json.dumps(self.manifest, indent=2))
Gap Analysis Tool
import logging
REQUIRED_CONTROLS: dict[str, list[str]] = {
"CC6.1": ["access_provisioning", "access_reviews", "mfa_enforcement", "privileged_access"],
"CC6.2": ["authentication_mechanisms", "password_policy", "session_management"],
"CC7.2": ["security_monitoring", "alert_triage", "incident_response"],
"CC8.1": ["change_management", "code_review", "deployment_approval"],
}
def run_gap_analysis(current: dict[str, list[str]]) -> dict:
gaps, done = [], []
for crit, required in REQUIRED_CONTROLS.items():
for ctrl in required:
if ctrl in current.get(crit, []):
done.append(f"{crit}/{ctrl}")
else:
gaps.append({"criteria": crit, "missing": ctrl,
"priority": "high" if crit in ("CC6.1", "CC7.2") else "medium"})
total = sum(len(v) for v in REQUIRED_CONTROLS.values())
return {"compliance_pct": round(len(done) / total * 100, 1), "gaps": gaps, "implemented": len(done)}
Configuration
| Parameter | Default | Description |
|---|---|---|
audit.period_months |
6 |
Length of audit observation period |
audit.sample_size |
25 |
Default sample size for control testing |
evidence.auto_collect |
true |
Enable automated evidence collection |
evidence.retention_years |
7 |
Years to retain audit evidence |
policies.review_frequency |
annual |
Policy document review cadence |
policies.approval_required |
true |
Require management sign-off on policies |
gap_analysis.risk_weights |
{"CC6.1": 1.5} |
Weight high-risk criteria higher |
Best Practices
- Start evidence collection on day one — SOC 2 Type II requires evidence across the entire observation period (6-12 months). Don't wait.
- Automate everything you can — Manual evidence collection doesn't scale. Use the included scripts.
- Assign control owners early — Every control needs a named owner, not a team.
- Run the gap analysis first — Know your gaps before writing policies.
- Keep policies concise — Auditors prefer a 3-page policy employees follow over a 30-page one nobody reads.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Gap analyzer shows 0% compliance |
current_controls.yaml format doesn't match expected schema |
Use the example file as a template; ensure control IDs match |
| Evidence collector misses some artifacts | Log files use non-ISO timestamp format | Configure evidence.timestamp_format to match your log format |
| Policy validator rejects valid policies | Missing required sections (scope, roles, review date) | Add all required sections per templates/policy_structure.yaml
|
| Auditor requests evidence not in manifest | Control was added after collection started | Re-run evidence collector with --incremental flag |
This is 1 of 9 resources in the Security Engineer Pro toolkit. Get the complete [SOC 2 Compliance Templates] with all files, templates, and documentation for $59.
Or grab the entire Security Engineer Pro bundle (9 products) for $119 — save 30%.
Top comments (0)