Skip to main content
INS // Insights

SOC 2 CC8.1: Automating Code Review Evidence

Updated August 2026 · 7 min read

Code deployments without documented review show up in 20-30% of audits as a recurring finding — third on the list behind access deprovisioning and access reviews, and arguably the easiest of the three to fully automate, because the evidence trail already exists inside most version control platforms. The gap isn't that reviews don't happen; it's that "documented" means something specific to an auditor, and most teams' actual review process doesn't consistently produce it.

What CC8.1 Actually Asks For

SOC 2's CC8.1 covers change management — the entity authorizes, designs, develops, configures, documents, tests, approves, and implements changes to infrastructure, data, software, and procedures to meet its objectives. For a software company, the sampled evidence is almost always pull request history: was every production change reviewed by someone other than the author, was it approved before merge, and is there a traceable link between the approved review and the deployed artifact.

The failure pattern isn't usually "no code review culture" — it's technical: branch protection not actually enforced on the branch that deploys to production, a review requirement that can be bypassed by an admin or a force-push, or a review that happened on a PR that was later modified without a re-review before merge.

Enforcing Review at the Platform Level, Not by Policy Document

# branch-protection.yml — GitHub branch protection ruleset (applied via API/Terraform)
name: "production-branch-protection"
target: "branch"
enforcement: "active"
conditions:
  ref_name:
    include: ["refs/heads/main"]
rules:
  - type: "pull_request"
    parameters:
      required_approving_review_count: 1
      dismiss_stale_reviews_on_push: true
      require_code_owner_review: true
      require_last_push_approval: true
  - type: "required_status_checks"
    parameters:
      required_status_checks:
        - context: "ci/build"
        - context: "ci/test"
  - type: "non_fast_forward"
  - type: "required_linear_history"

Two settings here close the gaps that undermine review evidence most often. dismiss_stale_reviews_on_push means an approval doesn't survive a post-approval code change — a common bypass where a reviewer approves, then the author pushes an unreviewed change before merging. require_last_push_approval closes the related gap where the last commit before merge wasn't the one that got reviewed. Without both, "we require code review" is true on paper and unenforced in the specific way an auditor's sample is most likely to catch.

# review_evidence_export.py — pull merged-PR review evidence for the audit period
import requests

def export_review_evidence(repo: str, since: str, until: str, token: str) -> list[dict]:
    prs = requests.get(
        f"https://api.github.com/repos/{repo}/pulls",
        params={"state": "closed", "base": "main"},
        headers={"Authorization": f"Bearer {token}"},
    ).json()

    evidence = []
    for pr in prs:
        if not pr.get("merged_at") or not (since <= pr["merged_at"] <= until):
            continue
        reviews = requests.get(pr["url"] + "/reviews",
                                headers={"Authorization": f"Bearer {token}"}).json()
        approvals = [r for r in reviews if r["state"] == "APPROVED"]
        evidence.append({
            "pr_number": pr["number"],
            "author": pr["user"]["login"],
            "merged_at": pr["merged_at"],
            "approvers": [a["user"]["login"] for a in approvals],
            "self_review_violation": pr["user"]["login"] in [a["user"]["login"] for a in approvals],
        })
    return evidence

The self_review_violation flag matters — it's checking for the specific separation-of-duties failure where an author approved their own change, which is possible in misconfigured repositories and is exactly the kind of finding an auditor's sample review will surface manually if you don't surface it first yourself.

Emergency Changes Need Their Own Documented Path

Every engineering org has emergency production fixes that can't wait for the standard review cycle — an active incident where a fix needs to ship in minutes, not after a normal PR review. CC8.1 doesn't require zero exceptions; it requires that exceptions are documented, authorized, and reviewed after the fact. Building an explicit "emergency change" label and workflow — post-hoc review required within a defined window, logged separately from standard changes — turns an audit gap into a documented, defensible exception category.

Frequently Asked Questions

Does every single commit need individual review, or is PR-level review sufficient?

PR-level review is the standard and generally sufficient — auditors sample at the PR/merge level, evaluating whether the complete set of changes in a PR was reviewed before merge, not whether every individual commit within it was separately reviewed.

What if we use trunk-based development with very short-lived branches?

The evidence model is the same regardless of branching strategy — what matters is that changes merged into the deployable branch went through an enforced review and approval step before merge, whether that branch lives for two minutes or two weeks.

Can automated code review tools (linters, static analysis) substitute for human review?

No, not for CC8.1 specifically — automated checks are valuable as required status checks alongside human review, but the control is asking about human authorization and approval of a change, which automated tooling doesn't provide on its own.

How do we handle admin/owner accounts that can bypass branch protection?

This is one of the most common findings — branch protection rules that exclude repository admins by default. Explicitly enabling "include administrators" (or the platform-equivalent setting) closes this gap; without it, the protection rule only binds non-admin contributors, which an auditor will test by checking whether admin-authored merges skipped review.

Does infrastructure-as-code (Terraform, CloudFormation) need the same review evidence as application code?

Yes, and arguably it matters more — infrastructure changes often have broader blast radius than application code changes. The same branch protection and PR review evidence pattern should apply to infrastructure repositories, and CI-enforced terraform plan output attached to the PR strengthens the evidence further by showing exactly what was reviewed before approval.


Rutagon builds change management evidence pipelines — branch protection enforcement, review evidence export, and emergency-change documentation mapped directly to CC8.1.

Ask us what your GRC platform isn't covering → rutagon.com/contact | 907-841-8407 | contact@rutagon.com

Related reading: SOC 2 Evidence for Internal Tools Auditors Ask About · SOC 2 CC7.1 Vulnerability Management Evidence · Security Automation Capability

External reference: AICPA Trust Services Criteria