Build SOC 2 and ISO 27001 Evidence Into the Pipeline
An auditor asks for three months of deployment approvals. Someone opens GitHub, starts clicking through workflow runs, and pastes screenshots into a spreadsheet. Two hours later, they discover that half the approvals happened in a different system and one repository stopped retaining logs weeks ago.
This is not an evidence problem. It is a system design problem.
If a control runs continuously, its evidence should be collected continuously. The pipeline already knows which commit was tested, which policies passed, who approved the deployment, and which artifact reached production. Throwing that context away and rebuilding it by hand at audit time is expensive and surprisingly easy to get wrong.
The useful goal is not to automate the audit. Auditors still need judgment, sampling, and context. The goal is to make control operation observable, repeatable, and boring.
Screenshots are a lossy evidence format
A screenshot can show that a setting existed at one moment. It rarely proves who changed it, how long it was active, or whether the same rule covered every repository in scope.
Good evidence answers a tighter set of questions:
- Which control does this support?
- What asset, repository, account, or environment was evaluated?
- When did the check run?
- Which code and policy versions were used?
- What was the result?
- Who approved an exception, and when does it expire?
- Can the record be altered without detection?
That last point gets missed. A pipeline log stored for a few weeks is useful operational data, but it is weak long-term evidence. Export the relevant result into an access-controlled evidence store with retention, versioning, and audit logging. In AWS, that might be an S3 bucket using Object Lock, restricted IAM roles, and CloudTrail data events. The equivalent controls exist in other clouds.
Do not dump every build log into the bucket and call it compliance. Evidence needs enough context to stand on its own without preserving a swamp of tokens, debug output, and unrelated personal data.
Start with the control, not the scanner
SOC 2 Trust Services Criteria and ISO 27001 controls describe outcomes. Your tools produce technical facts. The mapping between them is where most of the engineering work lives.
Take a change management control requiring reviewed changes before production deployment. GitHub branch protection configuration is design evidence. Pull request reviews are operating evidence. A deployment record connecting the reviewed commit to the production artifact completes the chain.
Represent that mapping as data rather than burying it in an audit workbook:
control_id: change-management-01
framework_refs:
- soc2: CC8.1
- iso27001: A.8.32
scope:
repositories: production-services
sources:
- github_branch_protection
- github_pull_request_reviews
- deployment_attestations
owner: platform-security
review_frequency: quarterly
retention_days: 400
The exact identifiers and retention period must come from your own control set, audit scope, contracts, and legal requirements. Copying somebody else's mapping creates impressive paperwork and weak assurance.
Keep control definitions versioned. A pull request changing a control mapping deserves the same review discipline as a Terraform change because it alters what the organisation claims to verify.
Make the build produce evidence
A practical devsecops pipeline should emit small, structured records at each security gate. SAST, software composition analysis, secret scanning, infrastructure policy, container security, and deployment approval can all produce machine-readable results.
For example, generate an SBOM with Syft and scan the image with Trivy:
syft "$IMAGE_DIGEST" -o cyclonedx-json > sbom.cdx.json
trivy image --format json --output trivy.json "$IMAGE_DIGEST"
Use the immutable image digest, not a mutable tag such as latest. Otherwise the SBOM and scan can quietly describe a different artifact from the one deployed.
Then attach provenance and evidence to that digest. Cosign can sign images and create attestations using workload identity, avoiding a long-lived signing key in CI:
cosign sign --yes "$IMAGE_DIGEST"
cosign attest --yes \
--type cyclonedx \
--predicate sbom.cdx.json \
"$IMAGE_DIGEST"
An SBOM is not proof that the software supply chain is safe. It is an inventory. Its value comes from tying dependencies to a specific artifact, recording the scanner and database versions, tracking exceptions, and proving which artifact was deployed.
Store a compact evidence envelope beside the detailed reports:
{
"control_id": "container-release-02",
"commit": "8c11f7d",
"artifact": "registry.example/app@sha256:...",
"workflow": "release.yml@refs/heads/main",
"result": "pass",
"policy_version": "security-policy@4a93c2b",
"collected_at": "2026-08-06T14:32:10Z"
}
In production, include the workflow run identifier, repository, environment, scanner versions, artifact locations, and the identity that signed the record. Validate the envelope against a JSON Schema before accepting it.
Policy as code needs receipts
Conftest and Open Policy Agent are useful because they turn review expectations into executable rules. They also produce evidence consistently across repositories.
A simple Rego rule can reject Kubernetes workloads that use mutable image tags:
package kubernetes.images
deny contains msg if {
container := input.spec.template.spec.containers[_]
not contains(container.image, "@sha256:")
msg := sprintf("container %s must use an image digest", [container.name])
}
Run it in CI and retain structured output:
conftest test deployment.yaml \
--policy policy/ \
--output json > conftest-results.json
The evidence must record the tested configuration and policy commit. A passing result without those inputs is almost meaningless. Policies change. So do manifests.
Failures matter too. If teams can bypass a gate, capture the exception ticket, approver, justification, affected asset, and expiry date. Reject permanent exceptions by default. A six-month-old waiver with no owner is not risk acceptance. It is forgotten work.
Cloud controls need history, not just current state
Pipeline evidence covers changes and artifacts, but SOC 2 and ISO 27001 scopes usually include controls outside CI. Identity settings, logging, backups, encryption, vulnerability handling, and production access all need evidence from their systems of record.
Prefer APIs and event streams over scheduled screenshots. AWS Config can preserve configuration history. CloudTrail records activity. GitHub and GitLab expose review and workflow metadata. Ticketing systems hold exception approvals. Your collector should normalize only what the control needs, attach the control identifier, and preserve a link to the source record.
Be careful with point-in-time queries. Asking whether encryption is enabled today does not demonstrate that it remained enabled throughout the audit period. Collect state changes, periodic evaluations, or both. Auditors testing operating effectiveness will care about the period, not just the afternoon before fieldwork.
Also monitor the evidence pipeline itself. Alert when a source stops reporting, a repository falls outside coverage, storage retention changes, or signing fails. Silence is not a passing control.
If you only do one thing this week
Pick one control that causes repeated screenshot collection, preferably deployment approval or repository protection. Write down the evidence fields an auditor actually needs. Then have the system emit one signed JSON record per control event into retained storage.
Do not begin by buying a compliance dashboard or wiring every scanner into one enormous workflow. Prove the chain for one control: requirement, technical check, result, artifact, identity, timestamp, retention, and exception path.
Once that chain works, repeat it. The payoff is bigger than faster evidence collection. Engineers can see whether controls are operating before an auditor asks, security checks are tied to every commit, build, and deploy, and compliance becomes an output of the delivery system instead of a seasonal archaeology project.
If this is on your plate, TecLeads does exactly this as part of our DevSecOps work. If you'd like a second pair of eyes on your setup, book a 30-minute call or explore what we do.