SOC 2 CI/CD Pipeline Controls: Change Management That Auditors Accept
Build a SOC 2-ready CI/CD pipeline — covering branch protection, required checks, deployment approval gates, pipeline audit trails, and evidence collection for CC8 change management.
- Every production deployment must trace back to a reviewed and approved pull request — no direct pushes to main.
- Require passing CI checks (tests, SAST, dependency scan) as branch protection status checks before merge.
- Use deployment environment gates with required reviewers for production deployments.
- Retain pipeline run logs for 12 months as CC8 change management evidence.
- Separate deployment credentials from development credentials — production deploy keys should require a second authorised principal.
In this guide
CC8 change management requirements
SOC 2 CC8 (Change Management) requires that changes to systems are authorised, tested, and documented before deployment to production. This applies to application code, infrastructure changes (Terraform), database migrations, and configuration changes.
The three questions auditors ask about CI/CD: (1) Can anyone push directly to the production branch? (2) Are there automated gates that prevent broken or insecure code from deploying? (3) Is there a record of who deployed what, when, and after whose approval?
A CI/CD pipeline that enforces these three requirements is a direct technical control for CC8. Auditors prefer technical controls (branch protection, required reviewers) over procedural controls (a policy document saying developers should get approval) because technical controls cannot be bypassed by accident.
Branch protection and required reviewers
Enable branch protection on main (or your production branch): require pull requests before merging, require a minimum of 2 approvals, dismiss stale reviews when new commits are pushed, require review from CODEOWNERS, and block force pushes and deletions.
The "Dismiss stale reviews" setting is critical. Without it, an attacker or careless developer could get approval, then add malicious commits to the approved PR without re-review. New commits after approval should reset the approval count.
For regulated repositories (infrastructure, security configurations), consider requiring signed commits: `git config commit.gpgsign true`. GitHub can enforce that all commits are signed: branch protection setting "Require signed commits". This links each commit to a verified developer identity.
Required status checks for security gates
Add the following CI jobs as required status checks in branch protection: (1) unit-tests — must pass. (2) integration-tests — must pass. (3) sast-scan — SAST tool (Semgrep, CodeQL) must pass with zero high/critical findings. (4) dependency-scan — npm audit or pip-audit must pass. (5) lint — code style and type checks must pass.
Mark each check as "required" in branch protection under "Require status checks to pass before merging". PRs cannot merge if any required check fails. This creates an automated gate that cannot be overridden by approvers.
Use CodeQL for SAST (free for public repos, included in GHAS for private repos). CodeQL analyses code flow and detects injection, authentication, and authorisation vulnerabilities with low false positive rates. Configure it to run on pull_request and push to main.
Deployment approval gates for production
Configure a GitHub Environment named "production" with required reviewers set to your senior engineers or a security team. Reference this environment in the deploy job: `environment: production`. The job pauses at the deploy step until an authorised reviewer approves in the GitHub UI.
Add a deployment protection rule that checks your change management ticket system: a custom deployment protection rule (GitHub App) can verify that a Jira or Linear ticket is linked to the PR before allowing deployment. This links deployments to your change management audit trail.
For infrastructure changes (Terraform), add a terraform plan output to the PR as a comment (use `github-script` or `hashicorp/setup-terraform`). Reviewers approve the plan, and the apply runs only after approval. Never run `terraform apply` on push without a plan review step.
Pipeline audit trail and log retention
Every pipeline run creates a record: who triggered it, which commit hash, which workflows ran, pass/fail status, and the deployment target. Export this data for long-term retention. GitHub Actions workflow run logs expire after 90 days by default.
Use GitHub Audit Log Streaming (GitHub Enterprise) to stream all audit events (repo push, workflow trigger, environment approval) to S3 or Splunk. For GitHub.com (non-Enterprise), use webhooks to capture `workflow_run` and `deployment` events to an S3 bucket.
At minimum, export a monthly snapshot of deployment history using the GitHub API: `GET /repos/{owner}/{repo}/deployments`. Store the JSON output with 12-month retention. This gives auditors a change history timeline covering the audit period.
Separating deployment credentials
Production deployment credentials (AWS IAM role, Kubernetes service account, cloud API keys) should be separate from development and staging credentials. Use different IAM roles with different permission scopes. Production roles should have only the permissions needed to deploy (ECR push, ECS service update) — not read access to production data.
Restrict which workflows can use production credentials. With GitHub OIDC, restrict the IAM role trust policy to only the specific workflow file: `"StringEquals": {"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:environment:production"}`. This prevents other workflows or repos from assuming the production role.
Rotate any long-lived production credentials quarterly, even if using OIDC for most deployments. Some deployment targets (database migration tools, legacy systems) still require static credentials. Track these in your secrets inventory and enforce rotation dates.
CI/CD SOC 2 checklist
Before your audit: (1) Direct push to main blocked by branch protection. (2) Minimum 2 PR approvals required. (3) Stale review dismissal enabled. (4) Required status checks: tests, SAST, dependency scan, lint. (5) Production environment with required reviewers. (6) Deployment run history exported with 12-month retention. (7) Production IAM role separate from staging/dev. (8) OIDC trust policy restricted to production environment.
Map evidence to CC8: branch protection screenshot → CC8.1 (change authorisation). CodeQL SAST results → CC8.1 (security testing in change process). Deployment environment approval logs → CC8.1 (change approval). GitHub Audit Log export → CC8.1 (change record).
Frequently Asked Questions
Do hotfixes need to go through the full CI/CD process?
Does infrastructure-as-code (Terraform) need to go through CI/CD?
What counts as a production change for SOC 2 purposes?
How do I handle emergency access that bypasses the pipeline?
Is a single CI/CD platform (GitHub Actions + GitHub) sufficient or do I need separate tools?
Automate your compliance today
AuditPath runs 86+ automated checks across AWS, GitHub, Okta, and 14 more integrations. SOC 2 and DPDP Act. Free plan available.
Start for free