Building a SOC 2 Evidence Collector With Inngest
SOC 2 audits eat weeks because evidence collection is manual. Here's an Inngest-based pipeline that pulls evidence continuously, organizes it by trust service criterion, and is ready when the auditor asks.
SOC 2 audits aren't expensive because of the auditor's fee. They're expensive because someone on your team spends weeks pulling evidence the auditor asks for.
Most of that evidence could have been collecting itself for a year. The pipeline below is what collecting it continuously looks like, and it turns SOC 2 preparation from a project into a report.
What evidence auditors actually want
For SOC 2 Type 2 (the common one), the auditor needs evidence that controls operated over the audit period (usually 6-12 months). The big categories:
- Access reviews: quarterly evidence that someone reviewed who has access to what
- Vulnerability scans: scan results, remediation timelines
- Change management: evidence of code review on production changes
- Incident response: evidence of incidents and how they were handled
- Backup tests: evidence backups were tested
- Onboarding/offboarding: evidence employees were properly onboarded and offboarded
- Vendor management: vendor list, attestations from each
- Risk assessment: annual risk assessment artifact
- Training: evidence security training was completed by each employee
Most of these can be collected automatically from systems you already use.
The pipeline
Inngest as the orchestrator. Each evidence type has a scheduled Inngest function that collects it on a defined cadence and lands the artifact in object storage with structured metadata.
Layer 1: Access review (quarterly cron).
For each system (AWS, Vercel, GitHub, Linear, Slack, etc.):
- Pull current user list with roles
- Compare against last quarter's snapshot
- Generate a diff doc showing additions / removals / role changes
- Save to S3 with metadata: {control: "CC6.1", period: "Q1-2026", system: "AWS"}The artifact is the diff doc, the user list, AND a sign-off entry that the responsible manager attested the access is appropriate. Collect the attestation via a Slack DM that links to the diff doc.
Layer 2: Vulnerability scan (weekly cron).
Run scans against production infra:
- AWS Inspector for AWS resources
- Snyk for dependencies
- Dependabot summary for repo-level
- Save scan results with metadata: {control: "CC7.1", scan_date, severity_summary}Layer 3: Change management (event-driven).
On every GitHub push to main:
- Capture commit metadata (author, reviewer, PR link)
- Verify required CI checks passed
- Verify the PR had at least one approving review
- Land an entry in the change log artifact
- Land daily summary to S3 with metadata: {control: "CC8.1", date}Layer 4: Incident response (event-driven).
On every Sentry alert or PagerDuty incident:
- Capture incident metadata
- Wait 24 hours, then ask the on-call: "What was the resolution?"
- Append the resolution narrative to the incident artifact
- After 30 days, run a postmortem prompt that generates a draft postmortemLayer 5: Onboarding/offboarding (event-driven).
On HR system change (Rippling, Gusto, etc.):
- New hire: trigger an onboarding checklist (account creation, security training assignment, manager attestation)
- Termination: trigger an offboarding checklist (account deactivation across all systems, attestation that access was removed)
- Each step generates a timestamped artifactLayer 6: Vendor management (monthly cron).
Read vendor list from a Notion database.
For each vendor:
- Check whether their SOC 2 attestation is in our drive and current
- Check whether their DPA is on file
- Flag any that are missing or expiring within 60 daysWhere Claude helps
Claude isn't doing the evidence collection. It's doing the analysis layer on top.
Trust service criterion mapping. Each piece of evidence has metadata about which control it supports. Claude verifies the mapping is correct and flags evidence that doesn't actually support the listed control.
Gap detection. Claude reads the audit framework and the evidence inventory and reports what's missing.
Auditor-ready packaging. When the audit starts, Claude takes a list of auditor requests and produces a packaged response with the relevant evidence linked.
How to measure it
Log the hours your team spends on audit prep this year, by evidence category, before the pipeline exists. Next year, log them again. The categories that barely moved are the ones to automate next.
What tends to break
Storage sprawl. Without strict naming, evidence ends up scattered across bucket prefixes. Set a strict path schema on day one and enforce it with a linting step.
Slack attestations get missed. A "please attest this" DM is easy to ignore. Add a scheduled function that re-pings after 48 hours, then escalates to the manager after a week.
Function sprawl. One function per evidence type multiplies quickly, and so does the bill. Consolidate similar functions into one with branching logic.
What this isn't
This isn't a substitute for a real security program. The evidence is only as good as the underlying controls. If your access review process is "we don't really do this," the system collects evidence of you not doing it.
It also isn't a substitute for a real auditor. The auditor still needs to test controls. The system makes their testing faster, not optional.
What to build first
Access reviews and change management. Both are large parts of the audit and among the easiest to automate.
Then incident response and vendor management. Both are valuable but require more system integration.
Then the rest in priority order based on which controls are biggest in your audit scope.
Get the next one.
Field notes from real deployments, written the way this one was. No schedule promised and nothing sold to you. Unsubscribe whenever.