A pattern we see repeatedly in SOC 2 Type II engagements: a company's controls are genuinely well-designed and consistently followed, but the evidence supporting that consistency exists in a form that only proves it for the specific instance someone happened to document — not for whatever random sample the auditor actually picks. The gap between "we do this control" and "we can prove we did this control for the specific dates and systems you're asking about" is where a lot of avoidable audit friction lives.
How Auditor Sampling Actually Works
SOC 2 Type II auditors don't review every instance of a control's operation across the audit period — they select a statistically-informed sample (the size depends on control frequency and the audit firm's methodology) and ask for evidence covering exactly those sampled instances. For a quarterly access review control, that might mean the auditor asks for evidence from Q2 specifically, for three particular employees, on the exact date the review was supposed to occur — not a general description of how the process works.
This is where manually-maintained evidence tends to fail even when the underlying control is real: someone documented "we do quarterly reviews," but producing the specific artifact for the specific sampled quarter and specific sampled users, on demand, without scrambling, requires the evidence to already exist in queryable form.
Building Evidence That Survives Any Sample
The architectural principle is simple to state and requires real engineering to implement: every control execution should produce a structured, timestamped, queryable record — not just an outcome, but the specific inputs, decision, and actor for that instance:
# Structured control-execution record designed for sampling
class ControlExecutionRecord:
def __init__(self, control_id, execution_date, scope, decisions, evidence_refs):
self.control_id = control_id # e.g. "access-review-quarterly"
self.execution_date = execution_date
self.scope = scope # which systems/users this instance covered
self.decisions = decisions # per-item outcome
self.evidence_refs = evidence_refs # pointers to underlying raw evidence
self.record_id = self._generate_id()
def matches_sample_request(self, date_range, entity_filter):
return (
date_range[0] <= self.execution_date <= date_range[1]
and any(entity_filter(d) for d in self.decisions)
)
With every control instance recorded this way, responding to an auditor's sample request becomes a query against structured data rather than a scramble to reconstruct what happened for a specific date and specific person.
Why This Matters More Than "Automating the Control Itself"
Teams sometimes over-index on automating the control's execution (which is valuable) while under-investing in automating the evidence that the control ran correctly for any given instance. A control can run perfectly and still fail the audit sample test if there's no queryable record proving it happened for the specific instance the auditor selected — automation of the control and automation of its evidence are related but distinct engineering problems, and both need to be solved.
Handling Controls That Involve Human Judgment
Not every control is a pure system check — access reviews, for instance, involve a human reviewer's judgment call about whether access is still appropriate. The evidence pipeline needs to capture that judgment as structured data (who reviewed, what they decided, when, based on what information) rather than treating the human step as an evidence gap just because it isn't a system-generated log entry. We build lightweight review UIs specifically to capture this decision data in a structured, sample-ready format rather than leaving it in email threads or Slack messages.
What This Looks Like When the Audit Actually Happens
The measurable outcome of building sample-ready evidence infrastructure isn't a smoother audit "in general" — it's a specific, repeatable moment: the auditor sends a sample request, and the answer comes from a query, typically same-day, instead of a multi-day internal scramble involving several people pulling records from memory and old spreadsheets.
This sample-ready evidence architecture builds on the pattern in SOC 2 evidence for internal tools, part of our security automation capability.
Ask us what your GRC platform isn't covering: 907-841-8407 or contact@rutagon.com.
Ask us what your GRC platform isn't covering →
Frequently Asked Questions
How large is a typical SOC 2 sample size?
It varies by control frequency and the audit firm's methodology — annual controls might see a sample of one, while daily or continuous controls typically see a larger, statistically-derived sample size across the audit period.
Can our existing GRC platform (Vanta, Drata, Secureframe) handle sample-ready evidence automatically?
For standard, well-integrated control types, often yes. The gap tends to appear for custom internal systems and human-judgment controls that fall outside the platform's native connectors — that's the layer we typically build.
What happens if we can't produce evidence for a specific sampled instance?
It typically becomes a control exception in the audit report, which can affect the audit opinion depending on severity and frequency — this is exactly the outcome sample-ready evidence infrastructure is designed to prevent.
Does this apply to SOC 2 Type I audits too?
Type I audits assess control design at a point in time rather than operating effectiveness over a period, so sampling is less central — this evidence architecture matters most for Type II audits and ongoing continuous compliance monitoring.
How far back does evidence typically need to be retained?
This depends on your audit period and any contractual or regulatory retention requirements, but retaining structured evidence for at least the full audit period (commonly 6-12 months for Type II) plus some buffer is standard practice.