SOC 2 secure software development and code review

SOC 2 does not prescribe a secure development method, but CC8.1 expects every software change to be authorized, tested and approved. This page explains what auditors sample, which self-hosted pipeline records prove it, and what to outsource.

On this page

What SOC 2 secure software development requires in practice

Picture a SaaS company whose largest customer now requires a SOC 2 report before renewal, while its engineers merge and deploy code several times a day. The first question its auditor will ask is how each software change is authorized, tested, approved and deployed. That expectation sits under criterion CC8.1, which covers every stage of a change to infrastructure, data, software or procedures. The organization owns these controls and must run them every time. Only an independent CPA firm can test them and issue the report.

The cost and duration of meeting CC8.1 depend on the scope of the examination and how mature the change evidence already is. A team that already requires peer review and records approvals in its tooling has less to build than one that approves changes in chat messages. No figures are given here because none are supplied for this topic. Ask any consultant or CPA firm to state, in writing, which systems and repositories are in scope, which evidence they will sample, and what remediation they expect before the examination window opens.

The work splits three ways. The organization defines its change policy, assigns approvers and keeps the records. DeployOpen plans, hardens and documents self-hosted pipelines and the evidence they produce, such as protected branch settings, review logs and scan results, inside the client's own infrastructure. The CPA firm then selects changes, inspects that approvals happened before deployment and tests whether the controls operated over the period. Agree on these boundaries before implementation starts so that nobody assumes another party owns a control gap.

Which development controls an auditor tests under CC8.1 and CC5.2

CC8.1 covers every change to infrastructure, data, software or procedures, and CC5.2 covers the technology controls that support business processes. The cards below set out the development controls an examiner typically samples and the records each one should leave behind.

Authorized change requests

Every change should start from a recorded request that names the change, its risk and the person who authorized it before work begins. Auditors commonly sample changes across the period and trace each one back to an approved request. Check that tickets link to the merge request, the deployment and the approval, and that changes made outside the workflow are caught. The request must exist before the change, not be written up afterward.

Separation of build and approval duties

The person who writes a change should not be the only person who approves and releases it. In a self-hosted pipeline this means the approver role is separate from the author role, and the runner or deployment account cannot approve its own output. Ask for the role matrix, the list of users with merge or deploy rights, and evidence that these rights were reviewed during the period. The author cannot be the sole approver.

Peer review before merge

Protected branches block direct pushes to the main line, so each change passes through a merge request that another qualified person reviews. Auditors look for the review record, the reviewer's identity and whether the reviewer could see the full diff. Free tiers of some platforms make approvals optional, so confirm the approval rule actually blocks merging in your edition. Record who reviewed each change and when.

Automated testing and scanning before deployment

Tests, static analysis and dependency scanning should run before code reaches production, and a failing result should stop the pipeline. Auditors ask for pipeline logs that show which checks ran for each change and how findings were resolved. Semgrep can run in CI/CD to scan repositories, and Trivy can generate a software bill of materials for dependencies. Confirm that failed checks block deployment and that exceptions are approved and logged.

Emergency change handling

Emergency fixes often skip normal review, which is why CC8.1 expressly considers changes needed in emergencies. Define what qualifies as an emergency, who may authorize it, and how the change is reviewed after the fact. Auditors will sample emergency changes and check for a retrospective approval and a link to the incident. Keep a documented post-hoc review for each emergency change so the exception is visible.

Technology acquisition and maintenance under CC5.2

CC5.2 expects controls over how technology is acquired, developed and maintained, including the security management processes around it. For self-hosted open-source platforms, this covers how components are selected, pinned to versions, patched and retired. Auditors ask for a component inventory, the baseline configuration and records of patch changes. Confirm that every deployed component has an owner and a recorded version.

Using NIST SP 800-218 as a shared secure development vocabulary

NIST SP 800-218 is a shared vocabulary for secure development, not a SOC 2 requirement. The Secure Software Development Framework (SSDF), *NIST SP 800-218*, Version 1.1 from February 2022, sets out a core group of high-level secure development practices that can be integrated into any software development lifecycle. Because it is written at that level, it gives software producers and purchasers a common set of terms for describing how code is secured. A SOC 2 examination does not test against it, and no criterion in the 2017 Trust Services Criteria names it. Your organization owns the decision to adopt it, and the mapping from its practices to the criteria, including CC8.1 on change authorization and testing, is work your organization and its CPA firm must agree on.

Using the SSDF well starts with a short internal exercise. Take each practice group, such as protecting the software, producing well-secured software, and responding to vulnerabilities, and ask which of your existing controls already satisfy it. For example, a protected branch in a self-hosted GitLab instance may support a practice about controlling changes to source code, while a required approval rule may be needed if you want a second reviewer enforced. Record the answer in your control matrix with the evidence location, such as merge request approvals or pipeline logs. Confirm with your auditor whether they want SSDF mentioned in the system description or only used internally as a reference. Read the NIST SP 800-218 publication before you start the mapping, since the practice definitions and their wording are the authoritative source.

Which self-hosted tools produce development evidence

Branch protection is usually the first evidence an assessor asks to see for CC8.1, because it shows who is allowed to alter production code and whether changes pass through a recorded review. GitLab Community Edition includes protected branches, which let maintainers restrict which roles can push or merge to a branch.

  • Direct push blocking: Setting push access to no one forces changes to arrive through merge requests rather than direct commits to the protected branch.
  • Role-restricted merging: Maintainers can limit merge rights to named roles, which gives a reviewable record of who could approve a release branch.
  • Force pushes disabled: Force pushes stay off unless explicitly allowed, which protects the commit history an auditor samples.
  • Approval limits on the Free tier: Required merge request approvals, approval rules and code owner approval need GitLab Premium or Ultimate. In the Free tier, approvals are optional and do not block merging, so a review requirement cannot be enforced by the platform alone.

Confirm current tier features with GitLab before you commit to a design, since feature placement can change between releases. Check the GitLab protected branches documentation and request a written tier comparison from the vendor.

Why the GitLab tier decides whether approvals block a merge

The GitLab tier decides whether an approval is enforced or only recorded. In the Free tier of GitLab Community Edition, approvals are optional and do not block merging, so a reviewer can click approve and the author can still merge without that approval. An auditor testing CC8.1 will ask whether a change could reach production without the review that the policy requires. If the answer is yes, the approval is evidence of good intent, not a control. Protected branches on Community Edition do close part of that gap: maintainers can restrict which roles push or merge, set push access to no one so that direct pushes are blocked, and keep force pushes disabled unless someone explicitly allows them. That stops unreviewed code from being written straight onto the branch that deploys, but it does not require a second person to approve the merge request itself.

Required merge request approvals, approval rules and code owner approval are the features that make the review a gate. According to GitLab's edition documentation, these need GitLab Premium or Ultimate. With them, the platform can hold a merge request until the required reviewers approve, and code owners can be required to sign off on changes to the files they own. Confirm the current feature list for each tier against the GitLab documentation and the LICENSE and README editions file in the gitlab-org/gitlab repository before you commit to a tier, because subscription terms change. If you self-host, also confirm which tier your license covers and who administers it.

Decide the tier before you draft the change management policy, not after. The policy will say that changes require independent approval before deployment, and the auditor will test that statement against the platform configuration and the merge history for sampled changes. If the tier cannot enforce the approval, either the policy must describe a compensating procedure that produces evidence, or the tier must change. Ask your engineering lead to show, on a test project, that a merge request without the required approval is refused, and keep that result as evidence for the auditor. Also decide who may change protected branch and approval settings, since an engineer who can edit those rules can remove the control.

How an auditor samples changes during the examination

The sequence moves from understanding how changes are supposed to flow to testing real change records against that design, so the auditor can state whether CC8.1 controls exist and, for a Type 2 report, operated throughout the period. Each step produces a named artifact that the next step depends on.

  1. Read the system description and control matrix

    The auditor starts with management's system description and the control matrix, which together state how changes are requested, built, tested, approved and deployed. The auditor, not the organization, decides which controls are in scope for testing. The output is a walkthrough plan listing each change control and the evidence expected for it. Confirm with your auditor early which change types, such as infrastructure, configuration, data and emergency changes, the description must cover, because gaps found here are cheaper to fix before fieldwork.

  2. Walk through one change end to end

    Before sampling, the auditor usually follows a single change from request to production to confirm the process works as written. In a self-hosted pipeline this means tracing an issue or ticket to a merge request, the protected branch it merged into, the CI job results and the deployment log. The output is a walkthrough memo that confirms the control design or records where it differs from the description.

  3. Define the population of changes

    For a Type 2 report, the auditor needs a complete population of changes made during the observation period. Completeness matters because a sample drawn from an incomplete list proves little. Ask your team to export merged merge requests, deployment records and emergency change logs from the self-hosted tools, and confirm the export matches the repository and deployment system. The output is a population listing with a stated source for each system.

  4. Select a sample of changes

    The auditor selects a sample from the population across the observation period, and may include emergency or out-of-process changes specifically. The selection method and sample size are the auditor's judgment under the engagement, so the organization should not choose which changes are shown. The output is a sample list the auditor records in the working papers. Ask the auditor how the population was validated and whether any changes were excluded and why.

  5. Request the evidence for each sampled change

    For each selected change, the auditor requests the ticket or issue, the merge request with its diff and review comments, the approval record, the pipeline results including testing and scanning output, and the deployment record showing the change reached production. Missing items are typically logged as exceptions to be explained. The output is a per-change evidence request list, and the team should prepare these artifacts in advance so retrieval does not depend on individuals.

  6. Compare each change against the control design

    The auditor checks that every sampled change matches the documented process: it was authorized, tested, approved by someone other than the author where the design requires it, and deployed as approved. The auditor also checks timing, such as whether approval came before deployment. The output is a test result per sample item, recorded as no exception or as an exception with a description. Exceptions are discussed with management before the report is drafted.

  7. Evaluate exceptions and conclude

    The auditor evaluates any exceptions for their nature and how many occurred, then forms a conclusion on the control. For a Type 1 report, the same design walkthrough is performed as of a single date rather than across a period, and the work concentrates on whether the controls are suitably designed and in place at that date. The output is the auditor's test results and, in the report, the opinion. The auditor issues the report, not the implementation partner or the organization.

Choosing between enforced pipeline controls and manual change records

This table compares fully enforced controls in a self-hosted pipeline with manual change tickets and spreadsheet approvals across evidence quality, upkeep and fit. Read each row as a trade-off: enforced controls produce stronger system-generated records but need platform configuration and tier checks, while manual records are quicker to start but depend on people completing them accurately.

FactorEnforced pipeline controlsManual change tickets and spreadsheets
Evidence qualityMerge and approval records are generated by the platform as the change moves through the pipeline, which an assessor can sample directly.Records depend on people filling in fields. Assessors often need extra corroboration that the approval happened before deployment.
Blocking unapproved changesProtected branches can stop direct pushes and block merges until required conditions are met, if the platform tier supports it.Nothing technically stops a change from being deployed without a ticket. Detection relies on later review.
Approval rulesRequired approvals and code owner approval need a paid GitLab tier, per GitLab's documentation. Confirm the tier before relying on them.Approvals can be recorded in any tool, but there is no enforced gate linking the approval to the deployed build.
Effort to set upRequires repository, branch and pipeline configuration, plus testing that the controls block what they should.Quick to start with a template, but the template needs to be adopted consistently by every team.
Effort to maintainRules must be reviewed when repositories, teams or pipelines change. Configuration itself becomes evidence to keep under change control.Ongoing reconciliation of tickets against deployments, which grows with release frequency.
Coverage of security scansSAST, dependency and secret scanning can run as pipeline jobs on every change, with results attached to the merge request.Scan results are usually pasted into tickets manually, if at all, which makes coverage harder to prove.
Fits best whenTeams deploy frequently from version-controlled code and want assessors to test samples from system records.Change volume is low, deployments are infrequent, or systems are not yet in version control.
Main riskGaps in branch rules, exceptions for administrators or disabled jobs can go unnoticed without periodic review.Approvals may be backdated or skipped in emergencies, and the spreadsheet itself becomes a control to protect.

Who owns the development controls and who prepares the evidence

The organization owns its controls. Its leadership sets the change management policy, names who may authorize a change and who may approve a release, and decides when a release is blocked. These decisions belong to people inside the company, and a SOC 2 auditor will ask who made them and whether they were followed. An implementation partner can draft the policy and configure the tools, but the organization must adopt the policy, staff the approver roles and enforce the blocking decision.

  • Change policy: Defines what counts as a change, which changes need authorization, and how emergency changes are handled.
  • Approvers: Named individuals or groups with documented authority, separated from the people who write the code where the organization can manage it.
  • Release blocking decision: The authority to stop a deployment when a scan fails or a review is missing, and a record of how that authority is used.
  • Exception handling: Who signs off on bypassing a gate and how the bypass is recorded and reviewed afterward.
  • Ongoing operation: Reviewing pipeline results and approvals on a regular cycle.

Check that the policy names real roles, that each approver has a documented reason for holding that authority, and that someone outside the delivery team can see when a gate was bypassed.

Questions buyers ask about SOC 2 development controls

Does SOC 2 require static application security testing (SAST)?

No criterion names SAST by name, but CC8.1 expects changes to software to be tested and approved before deployment, and an auditor will look for evidence that code is checked for defects and security issues before it ships. SAST is the most common way to show that check, so most teams that pass a SOC 2 run it in their pipeline. The control is the outcome: the organization chooses the method, documents why it fits the system, and keeps records showing it ran. Ask your auditor which tests they expect for your technology stack before you commit to a tool. Semgrep Community Edition is one open-source option for scanning many languages in CI/CD, and the AICPA Trust Services Criteria explain the change control expectations the test supports.

Is code review mandatory for a SOC 2 audit?

The criteria do not use the phrase code review, but CC8.1 expects changes to be authorized and approved before they are implemented, and a second person reviewing a change is the usual way teams show that. Auditors generally test whether approval is enforced by the system, not just written in a policy. In GitLab, that means protected branches that block direct pushes and require an approver. The documented approval rules and code owner approval need GitLab Premium or Ultimate, while the Free tier makes approvals optional and non-blocking. If your team runs on the Free tier, you need another enforced gate or a documented compensating control, and you should confirm with your auditor that it is acceptable before the observation period starts.

Can our own engineers configure the secure development pipeline?

Yes, and in most cases they should own it, because the organization owns its controls and the people who run the pipeline must be able to explain it to the auditor. An implementation partner can design the pipeline, set up protected branches, wire in scanners such as Semgrep or Trivy, and write the procedures, then hand over ownership with documented runbooks. The work that usually needs outside help is the first build, the mapping of each step to a criterion, and the evidence design. Ongoing changes to rules, tool versions and exceptions stay with your engineers. DeployOpen implements and documents self-hosted pipelines inside the client's own infrastructure, and scope, deliverables and timelines are agreed in writing before work starts.

How long must we keep secure development evidence for SOC 2?

The Trust Services Criteria set no retention period, so there is no fixed number of days or years in the criteria themselves. What the auditor needs is evidence covering the whole observation period of a Type 2 report, so records such as merge approvals, pipeline results, scan findings and exception decisions must still be retrievable for every sampled change. Many organizations keep them for the length of the audit period plus whatever their own policy and customer contracts require. Confirm the retention period with your auditor and your contracts, write it into your retention policy, and test that you can pull a sample from several months earlier.

Are open-source tools accepted as evidence for SOC 2 development controls?

The criteria do not approve or reject specific products. An auditor accepts a tool when it produces reliable, reviewable records of the control it is meant to perform, and when the organization can show who configured it, what it checks and how findings are handled. Open-source tools such as GitLab Community Edition, Semgrep Community Edition and Trivy can meet that test if the configuration is version-controlled, the outputs are retained and the team can explain its rules. Check the license and edition limits before you rely on a feature, since some approval and scanning capabilities depend on the paid tiers. Ask your auditor to review the tool set early, because the question is usually whether the evidence is complete, not whether the tool is open source.

What does the work need from engineering leads?

Engineering leads need to decide the change process, own the approval rules and accept the operational cost of a gate that actually blocks unreviewed code. In practice that means naming who can approve production changes, agreeing how emergency changes are handled and recorded, and deciding how scanner findings are triaged and what severity stops a release. They also need to make sure every repository follows the same protected branch settings, because auditors sample across projects. Expect a few weeks of tuning as false positives are reviewed and rules are adjusted, and plan for that time in your sprint schedule. A written quote from any partner should list which of these decisions the partner will facilitate and which your leads must make.

Do we need a penetration test as part of secure development?

SOC 2 does not require a penetration test by name, but CC7.1 and CC4.1 expect the organization to identify vulnerabilities and check whether controls work, and penetration testing is a common way to do that. Static scanning and dependency checks run on every change, while a penetration test examines the running system from outside. Whether one is needed, and how often, depends on your system description and your customers' expectations, so confirm that with your auditor. DeployOpen runs application and API security testing as a separate service, and a test performed by an independent tester is treated differently from the scanners your own pipeline runs.

How DeployOpen prepares development evidence for the audit

DeployOpen plans, implements and hardens self-hosted open-source development platforms inside the client's own infrastructure, then prepares the change management and code review evidence that the organization's CPA firm will sample. DeployOpen prepares systems and evidence only; the organization owns its controls and the independent CPA firm issues the report.

How we scope

  • The written scope names which repositories, branches, pipelines and approval rules fall within the SOC 2 system boundary.
  • Scope lists the change types covered, including application code, infrastructure as code, configuration and emergency changes.
  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before any work starts.

How we build

  • We configure protected branches so that direct pushes are blocked and force pushes stay disabled unless explicitly allowed.
  • We set up SAST, secret detection and dependency scanning in self-hosted pipelines so each merge request produces recorded results.
  • We confirm with the client which approval features their GitLab tier supports, since required approvals and code owner approval need a paid tier.

How we hand over

  • We document the change workflow, approval roles and pipeline gates so the auditor can trace a change from request to deployment.
  • We deliver sample evidence packs of merge requests, approvals, scan results and deployment records for the control owner to review.
  • We provide a control mapping showing which CC8.1 points of focus each configuration and record addresses, for the auditor to assess.

How we support

  • Ongoing support, upgrades and continuous security testing are available as retainers after the initial handover.
  • Retainers can cover pipeline maintenance, scanner rule updates and periodic review of branch protection settings.
  • Before the observation period starts, we recommend confirming the evidence retention approach with the organization's CPA firm.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.