Evidence as Code

Evidence pipeline showing automated compliance artefact generation, versioning, and multi-framework reuse

Learning Objectives

By the end of this chapter, you will be able to:

  • Describe the characteristics of machine-generated compliance evidence and explain why deterministic capture is preferable to manual attestation.
  • Design a CI/CD pipeline that produces, packages, and publishes evidence bundles with framework metadata attached.
  • Generate a Software Bill of Materials (SBOM) and integrate it into an evidence collection workflow.
  • Implement cryptographic attestation to create tamper-evident supply chain artefacts using SLSA principles.
  • Map evidence artefacts to multiple regulatory frameworks using the assure once, comply many principle to eliminate duplicate audit effort.

Evidence is the currency that allows Architecture as Code to demonstrate trustworthiness at scale. Treating evidence as code means the artefacts that prove compliance are generated automatically, stored alongside the controls they verify, and versioned so that their provenance is unquestionable. Combined with the assure once, comply many principle, evidence captured for a single control objective can be replayed across multiple regulatory frameworks without repeating manual audits.

Machine-collected, versioned artefacts

Evidence as Code systems collect machine-readable outputs—policy evaluation reports, Terraform plans, cloud configuration snapshots, build logs—directly from delivery pipelines. Artefacts are stored in immutable storage with cryptographic signing and metadata that references the originating control, environment, and timestamp. By keeping these artefacts in the same repositories as policies and blueprints, teams create a living catalogue that auditors can browse without requesting ad hoc exports.

Key characteristics include:

  • Deterministic capture: Evidence is generated from automated checks, not manual screenshots.
  • Traceability: Artefacts link back to commit SHAs, pull requests, and ticket references.
  • Reusability: Metadata enumerates which frameworks and obligations each artefact supports, avoiding duplicate test runs.
  • Version control: Evidence follows the same branching strategy as code so historic attestations remain discoverable.

Pipeline example: exporting MFA evidence

The following pseudo-CI configuration shows how one control—the enforcement of multi-factor authentication for human identities—produces artefacts that downstream reporting systems can reuse.

jobs:
  verify-mfa:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Evaluate MFA policy
        run: opa test policies/identity --format=json > artefacts/policy-report.json
      - name: Snapshot cloud identities
        run: |
          SNAPSHOT_DATE=$(date +%Y%m)
          python scripts/export_mfa_snapshot.py \
            --accounts production \
            --output "artefacts/mfa-snapshot-${SNAPSHOT_DATE}.json"
      - name: Publish evidence package
        run: |
          SNAPSHOT_DATE=$(date +%Y%m)
          jq --arg filepath "artefacts/mfa-snapshot-${SNAPSHOT_DATE}.json" \
            --arg control "SEC-ID-001" \
            --argjson mappings '{"iso_27001":["A.5","A.8"],"soc_2":["CC6.1","CC6.6"],"nist_800_53":["IA-2(1)","AC-2"],"gdpr":["Article 32"],"internal":["SEC-ID-001"]}' \
            -n '{
              "control_id": $control,
              "framework_mappings": $mappings,
              "artefacts": [
                "artefacts/policy-report.json",
                $filepath
              ]
            }' > artefacts/manifest.json
      - name: Upload evidence bundle
        uses: actions/upload-artifact@v4
        with:
          name: sec-id-001
          path: artefacts/

The job produces a manifest and two evidence files. Governance and compliance teams consume the manifest to update the Control Mapping Matrix and to demonstrate coverage across ISO 27001, SOC 2, NIST 800-53, GDPR, and internal catalogues. Because the artefacts live alongside the policy, they can be retrieved for regulator-specific attestations without re-running the control unless configuration changes occur.

Software Bill of Materials as Evidence

A Software Bill of Materials (SBOM) is a machine-readable inventory of every component, library, and dependency in a software artefact. Regulatory frameworks such as the US Executive Order on Improving the Nation's Cybersecurity and the EU Cyber Resilience Act increasingly require SBOM disclosure. Generating SBOMs as part of the build pipeline transforms them from a one-off compliance exercise into continuous evidence.

Generating SBOMs with Syft

Syft produces SBOMs in CycloneDX and SPDX formats directly from container images or directory trees:

# Generate a CycloneDX SBOM from a container image
syft my-service:latest -o cyclonedx-json > artefacts/sbom-cyclonedx.json

# Generate an SPDX SBOM from a Python project directory
syft dir:. -o spdx-json > artefacts/sbom-spdx.json

Integrating SBOM generation into CI

- name: Generate SBOM
  uses: anchore/sbom-action@v0
  with:
    image: ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
    artifact-name: sbom-${{ env.IMAGE_TAG }}.spdx.json
    output-file: artefacts/sbom.spdx.json
    format: spdx-json

- name: Scan SBOM for vulnerabilities
  uses: anchore/scan-action@v3
  with:
    sbom: artefacts/sbom.spdx.json
    output-format: json
    output-file: artefacts/vulnerability-report.json
    fail-build: true
    severity-cutoff: critical

- name: Attach SBOM to evidence manifest
  run: |
    python3 - <<'EOF'
    import json, datetime, hashlib, pathlib

    sbom_path = pathlib.Path("artefacts/sbom.spdx.json")
    sbom_hash = hashlib.sha256(sbom_path.read_bytes()).hexdigest()

    manifest = {
        "control_id": "SEC-SUPPLY-001",
        "generated_at": datetime.datetime.utcnow().isoformat() + "Z",
        "framework_mappings": {
            "nist_ssdf": ["PO.1.3", "PS.3.1"],
            "iso_27001": ["A.12.6.1"],
            "soc_2": ["CC7.1"],
            "executive_order_14028": ["Section 4(e)"]
        },
        "artefacts": [
            {"path": "artefacts/sbom.spdx.json", "sha256": sbom_hash}
        ]
    }
    pathlib.Path("artefacts/sbom-manifest.json").write_text(json.dumps(manifest, indent=2))
    print("SBOM evidence manifest written.")
    EOF

Vulnerability tracking as continuous evidence

The vulnerability report produced by the scan step becomes an evidence artefact in its own right. Storing it alongside the SBOM creates a time-stamped record that demonstrates the organisation actively monitors its software supply chain—a requirement under frameworks such as NIST SP 800-53 SI-2 (Flaw Remediation).

Attestation Frameworks and Tamper-Evident Artefacts

Evidence value erodes if consumers cannot verify it was produced by trusted systems using approved processes. Cryptographic attestation addresses this by binding artefacts to verifiable claims about how they were created.

SLSA provenance

Supply chain Levels for Software Artefacts (SLSA) defines a framework for describing and verifying the provenance of software. A SLSA provenance attestation records the build system, source repository, build steps, and output digests, signed by the build platform's identity:

{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://slsa.dev/provenance/v1.0",
  "subject": [
    {
      "name": "my-service",
      "digest": { "sha256": "abc123..." }
    }
  ],
  "predicate": {
    "builder": { "id": "https://github.com/actions/runner" },
    "buildType": "https://github.com/slsa-framework/slsa-github-generator/container@v1",
    "invocation": {
      "configSource": {
        "uri": "git+https://github.com/myorg/my-service@refs/heads/main",
        "digest": { "sha1": "def456..." },
        "entryPoint": ".github/workflows/release.yml"
      }
    },
    "buildConfig": {},
    "metadata": {
      "buildStartedOn": "2026-01-15T09:00:00Z",
      "buildFinishedOn": "2026-01-15T09:12:00Z",
      "completeness": {
        "parameters": true,
        "environment": true,
        "materials": true
      }
    }
  }
}

Storing signed provenance alongside every release artefact allows downstream consumers—internal teams, regulators, or customers—to independently verify the artefact's build chain without trusting the producing organisation's word alone.

Cosign for container image signing

Cosign signs container images and stores signatures in the same registry as the image, making verification straightforward:

# Sign the image with a key stored in Google Cloud KMS
cosign sign \
  --key gcpkms://projects/my-project/locations/europe-west2/keyRings/ci/cryptoKeys/signing \
  my-registry/my-service:v1.2.3

# Verify the signature before deploying
cosign verify \
  --key gcpkms://projects/my-project/locations/europe-west2/keyRings/ci/cryptoKeys/signing \
  my-registry/my-service:v1.2.3

Admission controllers in Kubernetes clusters (for example, using Sigstore's Policy Controller) can enforce that only signed and verified images are permitted to run, creating a continuous attestation chain from source code to production workload.

Evidence Lifecycle Management

Evidence has a useful life that varies by regulatory context. Some frameworks require evidence retention for one year; others mandate seven years or more. A systematic approach to evidence lifecycle management prevents both premature deletion and uncontrolled accumulation:

Lifecycle Stage Activity Tooling
Capture Automated pipeline step produces artefact OPA, Syft, Cosign, cloud CLI tools
Packaging Evidence manifest links artefacts to control IDs and framework mappings Python/jq scripts, custom GitHub Actions
Storage Artefacts stored in immutable object storage with versioning AWS S3, Azure Blob, Google Cloud Storage
Indexing Manifest registered in evidence catalogue for audit queries SQLite, PostgreSQL, or a dedicated GRC platform
Retrieval Auditors or automated tools query catalogue by control ID or framework REST API, direct database query
Expiry Artefacts past retention period are archived or deleted per policy Lifecycle rules on object storage
Access Control Tamper-evident evidence stores require IAM/RBAC governance to restrict who can write, read, and delete evidence artefacts; least-privilege policies should be codified and reviewed regularly AWS IAM, Azure RBAC, Google Cloud IAM; OPA-enforced bucket policies

Integrating with governance and blueprints

Governance as Code defines the approval guardrails that keep evidence pipelines authoritative. Policy and Security as Code contributes reusable policy modules enriched with metadata for framework mapping. Security Fundamentals explains how control objectives become executable assertions, while Compliance and Regulatory Adherence uses the Control Mapping Matrix to translate artefacts into regulator-friendly language. Platform teams embed these patterns into their blueprints, as described in FINOS Project Blueprint, so that every environment exports evidence in a predictable manner. Together these chapters show how evidence captured once can sustain multiple obligations throughout the delivery lifecycle.

Summary

Evidence as Code transforms compliance from a periodic, manual exercise into a continuous, automated discipline. Machine-generated artefacts captured at each pipeline run provide auditors with verifiable proof that controls were active at specific points in time, eliminating the scramble to reconstruct evidence at audit season. SBOMs extend this visibility into the software supply chain, while cryptographic attestation—through SLSA provenance and Cosign signatures—ensures that evidence consumers can independently verify the integrity of what they receive.

The evidence lifecycle framework connects capture, packaging, storage, and retrieval into a coherent system that serves multiple frameworks simultaneously. When combined with the assure once, comply many principle, a single investment in evidence infrastructure yields dividends across ISO 27001, SOC 2, NIST 800-53, GDPR, and any future obligation the organisation encounters. This is not merely an efficiency gain; it is a structural shift in how organisations relate to compliance—from reactive to proactive, from opaque to transparent, from manual to automated.

Sources