Skip to content
Knowledge base

Machine-readable security attestations — automating compliance in CI/CD

Static compliance reports cannot keep pace with modern development. Machine-readable security attestations enable automatic security verification on every CI/CD pipeline run.

The traditional security verification model relies on static reports — PDF documents generated after audits, quarterly compliance reviews, spreadsheets with control checklists. This model cannot keep pace with modern software development, where teams deploy dozens of times a day and the supply chain encompasses hundreds of open-source dependencies.

ENISA’s Security by Design and Default Playbook proposes a fundamental shift: from document-based compliance to machine-driven verification. Machine-readable security attestations — security claims in structured formats — enable automatic generation, updating, and verification of security evidence within CI/CD pipelines.

The problem with static compliance

Quarterly audits vs. 50 deploys per day

Organizations subject to regulations (NIS2, DORA, ISO 27001) must demonstrate compliance with security requirements. Traditionally, this means:

  1. An auditor visits once per year or quarter
  2. The team prepares documentation for weeks
  3. The auditor verifies the state on the audit day
  4. A PDF report goes on the shelf

Between audits, the system may undergo hundreds of changes. Each potentially impacts the security posture. A PDF report from March says nothing about the system’s state in June.

Distributed responsibility

In the DevOps model, security responsibility is distributed across development, operations, and security teams. Each team uses different tools, generates different artifacts, follows different processes. The lack of a centralized, machine-readable source of truth about security posture leads to gaps and inconsistencies.

Supply chain — invisible risk

Modern applications consist of 70-90% open-source components. Each dependency is a potential vulnerability. Incidents like Log4Shell, SolarWinds, and event-stream demonstrated that compromising a single component can have cascading impact on thousands of organizations. Static reports cannot track this dynamic threat landscape.

What are machine-readable security attestations?

A machine-readable security attestation is a structured declaration in JSON, YAML, or another parseable format that states a specific security control has been implemented or a specific condition has been met.

Key characteristics

  • Automatically generated — produced as output from pipeline tools
  • Automatically updated — every code change generates a new set of attestations
  • Automatically verifiable — the deployment system checks attestations before allowing a release
  • Cryptographically signed — cannot be forged or modified without detection
  • Linked to artifacts — each attestation is uniquely tied to a specific build version

Anatomy of an attestation

Example attestation in in-toto format:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "app-server",
      "digest": {
        "sha256": "a1b2c3d4e5f6..."
      }
    }
  ],
  "predicateType": "https://slsa.dev/provenance/v1",
  "predicate": {
    "buildDefinition": {
      "buildType": "https://github.com/actions/runner",
      "externalParameters": {
        "workflow": ".github/workflows/build.yml",
        "ref": "refs/tags/v2.1.0"
      }
    },
    "runDetails": {
      "builder": {
        "id": "https://github.com/actions/runner/v2"
      },
      "metadata": {
        "invocationId": "https://github.com/org/repo/actions/runs/123456",
        "startedOn": "2026-04-09T10:00:00Z",
        "finishedOn": "2026-04-09T10:15:00Z"
      }
    }
  }
}

This attestation states: artifact app-server with a specific hash was built by GitHub Actions runner, from a specific workflow, from tag v2.1.0. Every element is verifiable.

Security control attestation

Beyond provenance, attestations can confirm security scan results:

{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "app-server",
      "digest": { "sha256": "a1b2c3d4e5f6..." }
    }
  ],
  "predicateType": "https://example.com/security-scan/v1",
  "predicate": {
    "scanner": "trivy",
    "scanType": "vulnerability",
    "timestamp": "2026-04-09T10:12:00Z",
    "results": {
      "critical": 0,
      "high": 0,
      "medium": 3,
      "low": 12
    },
    "policy": {
      "maxCritical": 0,
      "maxHigh": 0,
      "result": "PASS"
    }
  }
}

SLSA Framework — supply chain security levels

Supply-chain Levels for Software Artifacts (SLSA, pronounced “salsa”) is a framework developed by Google that defines four levels of software supply chain security. Each level requires increasingly rigorous attestations.

SLSA levels

SLSA Level 1 — Provenance exists

  • Documentation of the build process
  • Automatically generated provenance attestation
  • Minimum: it is known who built the artifact and how

SLSA Level 2 — Hosted build

  • Build executed on a hosted service (not locally)
  • Provenance generated by the build service, not the developer
  • Provenance authenticity is verifiable

SLSA Level 3 — Hardened builds

  • Build process isolation from the developer
  • Provenance cannot be forged by anyone with repository access
  • Build is hermetic — deterministic and reproducible

SLSA Level 4 — Two-person review

  • All changes require review by two people
  • Hermetic, reproducible build
  • Provenance includes complete dependency tree

Implementing SLSA in GitHub Actions

name: SLSA Build
on:
  push:
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
      attestations: write

    steps:
      - uses: actions/checkout@v4

      - name: Build application
        run: |
          npm ci
          npm run build
          tar -czf dist.tar.gz dist/

      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          artifact-name: sbom.spdx.json
          output-file: sbom.spdx.json

      - name: Scan vulnerabilities
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          format: 'json'
          output: 'trivy-results.json'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'

      - name: Generate attestation
        uses: actions/attest-build-provenance@v1
        with:
          subject-path: 'dist.tar.gz'

      - name: Verify attestation
        run: |
          gh attestation verify dist.tar.gz \
            --owner ${{ github.repository_owner }}

SBOM — Software Bill of Materials

SBOM is a complete inventory of all software components — libraries, frameworks, tools, and their versions. In the context of security attestations, SBOM serves as the foundation — without knowing what software is made of, its security cannot be assessed.

SBOM formats

CycloneDX — a format developed by OWASP, designed specifically for security. It supports not only components but also vulnerabilities, licenses, and services.

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "version": 1,
  "metadata": {
    "timestamp": "2026-04-09T10:00:00Z",
    "component": {
      "type": "application",
      "name": "app-server",
      "version": "2.1.0"
    }
  },
  "components": [
    {
      "type": "library",
      "name": "express",
      "version": "4.18.2",
      "purl": "pkg:npm/express@4.18.2",
      "hashes": [
        {
          "alg": "SHA-256",
          "content": "abc123..."
        }
      ]
    }
  ],
  "vulnerabilities": [
    {
      "id": "CVE-2024-XXXXX",
      "source": { "name": "NVD" },
      "ratings": [
        { "severity": "medium", "score": 5.3 }
      ],
      "affects": [
        { "ref": "pkg:npm/express@4.18.2" }
      ],
      "analysis": {
        "state": "not_affected",
        "justification": "code_not_reachable"
      }
    }
  ]
}

SPDX — a Linux Foundation format, more widely used in the context of open-source licenses but also supporting security information.

Automatic SBOM generation

SBOM should be generated automatically with every build:

# GitLab CI example
generate-sbom:
  stage: security
  image: anchore/syft:latest
  script:
    - syft dir:. -o cyclonedx-json > sbom.json
    - grype sbom:sbom.json --fail-on high
  artifacts:
    paths:
      - sbom.json
    reports:
      cyclonedx: sbom.json

In-toto — supply chain attestation framework

in-toto is a framework developed by NYU and NJIT that defines an attestation standard for the entire software supply chain. It enables defining a layout — a description of all steps that must be performed, by whom, and in what order.

In-toto architecture

Layout (pipeline definition)
  ├── Step: code-review
  │   ├── Expected command: git merge --verify-signatures
  │   └── Required signer: reviewer-key
  ├── Step: build
  │   ├── Expected command: npm run build
  │   └── Required signer: ci-runner-key
  ├── Step: security-scan
  │   ├── Expected command: trivy image ...
  │   └── Required signer: ci-runner-key
  └── Step: deploy-approval
      ├── Expected command: kubectl apply ...
      └── Required signer: deployer-key

Each step generates a link — a signed attestation confirming execution. The verification system checks that all steps were executed, by the correct people/systems, in the correct order.

Pipeline integration

# GitHub Actions with in-toto
- name: Record build step
  uses: in-toto/in-toto-run-action@v1
  with:
    step-name: build
    signing-key: ${{ secrets.IN_TOTO_KEY }}
    products: dist/
    command: npm run build

- name: Record security scan
  uses: in-toto/in-toto-run-action@v1
  with:
    step-name: security-scan
    signing-key: ${{ secrets.IN_TOTO_KEY }}
    materials: dist/
    command: trivy fs --exit-code 1 --severity HIGH,CRITICAL dist/

Sigstore — artifact signing and verification

Sigstore is a Linux Foundation project providing infrastructure for signing and verifying software artifacts. Its key component: cosign — a tool for signing container images and other artifacts.

Artifact signing

# Sign a container image
cosign sign --key cosign.key registry.example.com/app:v2.1.0

# Verify signature
cosign verify --key cosign.pub registry.example.com/app:v2.1.0

# Attach attestation to image
cosign attest --predicate sbom.json \
  --type cyclonedx \
  --key cosign.key \
  registry.example.com/app:v2.1.0

# Verify attestation
cosign verify-attestation --type cyclonedx \
  --key cosign.pub \
  registry.example.com/app:v2.1.0

Keyless signing with Fulcio

Sigstore also offers keyless signing — signing without key management. The signer’s identity is verified through OIDC (e.g., GitHub account), and proof of signature is recorded in a public, immutable log (Rekor).

# Keyless signing — identity from OIDC
cosign sign --identity-token=$(gcloud auth print-identity-token) \
  registry.example.com/app:v2.1.0

Automated gatekeeping — blocking unsafe releases

A critical element of machine-readable attestations is the ability to automatically block releases that do not meet security requirements.

Kubernetes admission policies

# Kyverno policy — requires signed image and SBOM attestation
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-signed-images
spec:
  validationFailureAction: Enforce
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences: ["registry.example.com/*"]
          attestors:
            - entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      ...
                      -----END PUBLIC KEY-----
          attestations:
            - type: https://cyclonedx.org/bom/v1.5
              conditions:
                all:
                  - key: "{{ vulnerabilities[?ratings[?severity=='critical']] | length(@) }}"
                    operator: Equals
                    value: "0"

CI/CD release gates

# GitHub Actions — gate checking attestations
release-gate:
  needs: [build, security-scan, sbom-generation]
  runs-on: ubuntu-latest
  steps:
    - name: Verify all attestations present
      run: |
        # Check provenance
        gh attestation verify dist.tar.gz --owner $GITHUB_REPOSITORY_OWNER

        # Check scan results
        CRITICAL=$(jq '.results.critical' trivy-results.json)
        HIGH=$(jq '.results.high' trivy-results.json)

        if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
          echo "RELEASE BLOCKED: Found $CRITICAL critical, $HIGH high vulnerabilities"
          exit 1
        fi

        # Check SBOM
        if [ ! -f sbom.json ]; then
          echo "RELEASE BLOCKED: SBOM not generated"
          exit 1
        fi

        echo "All gates passed — release approved"

ENISA playbooks as living artifacts

ENISA designs its playbooks not as static documents but as living artifacts integrated into the development process. Each playbook contains:

  1. Principle — e.g., “All artifacts must have verifiable provenance”
  2. Objective — e.g., “Ensure supply chain integrity”
  3. Checklist — specific steps to execute
  4. Minimum evidence — what attestations must exist
  5. Release gate — pass/fail criteria

Mapping playbooks to pipelines

Playbook: Supply Chain Integrity
├── Checklist item: SBOM generation
│   └── Pipeline stage: generate-sbom → artifact: sbom.json
├── Checklist item: Vulnerability scan
│   └── Pipeline stage: security-scan → artifact: trivy-results.json
├── Checklist item: Build provenance
│   └── Pipeline stage: build → attestation: slsa-provenance.json
├── Checklist item: Signature verification
│   └── Pipeline stage: sign → cosign signature
└── Release gate: ALL attestations present + no CRITICAL/HIGH vulns
    └── Pipeline stage: release-gate → PASS/FAIL

This structure enables automatic verification of ENISA playbook compliance on every pipeline run — not once a quarter during an audit.

Supply chain transparency

Machine-readable attestations solve the fundamental trust problem in complex digital ecosystems. They create a tamper-evident, continuous record of a product’s security posture — from the first line of code to production deployment.

Automating trust relationships

Instead of relying on one-time vendor audits, organizations can require continuous, verifiable attestations. A component supplier delivers:

  • SBOM of their dependencies
  • Provenance attestations (where the artifact came from)
  • Vulnerability scan results
  • Cryptographic signatures confirming integrity

The consumer can automatically verify these attestations before incorporating the component into their product — meeting NIS2 requirements for supply chain security.

Continuous risk visibility

Machine-readable attestations enable stakeholders to access a consistent and current view of risk. A security dashboard can show in real time:

  • Attestation status for each component
  • SBOM coverage across the supply chain
  • Vulnerability trends over time
  • Security policy compliance per release

Getting started — implementation roadmap

Step 1: SBOM for existing applications

Start by automatically generating SBOM for your applications. Tools like Syft (Anchore), cdxgen (CycloneDX), or Trivy can generate SBOM from existing code without pipeline modifications.

Step 2: Dependency vulnerability scanning

Connect a vulnerability scanner to your SBOM — Grype, Trivy, or Dependency-Track. Set up alerts for new vulnerabilities in components you use.

Step 3: Artifact signing

Deploy cosign to sign container images or build artifacts. Start with keyless signing via Sigstore — zero key management overhead.

Step 4: Release gates

Add automated security gates to your pipeline — first as warnings (soft fail), then as blockers (hard fail).

Step 5: Admission policies

Deploy policies in Kubernetes (Kyverno, OPA Gatekeeper) or other runtime environments that require valid attestations before deployment.

Conclusion

Machine-readable security attestations are not a futuristic vision — they are tools available today. SLSA, in-toto, Sigstore, CycloneDX — the entire ecosystem is open source and ready for deployment.

ENISA’s playbook formalizes what DevSecOps leaders have been implementing for years: security must be verifiable automatically, continuously, and by machines. Static PDF reports cannot keep pace with modern development. Machine-readable attestations can.

Key takeaways:

  • Attestations replace reports — JSON/YAML instead of PDF, continuous verification instead of point-in-time audits
  • SLSA defines levels — from basic provenance (L1) to hermetic, reproducible builds (L4)
  • SBOM is the foundation — without knowing your components, there is no supply chain security
  • Cryptographic signing ensures integrity and authenticity
  • Automated gatekeeping blocks unsafe releases before they reach production
  • ENISA playbooks map directly to CI/CD pipeline stages

Need help implementing security attestations in your pipeline? Contact our team — we will help design and deploy a secure software supply chain.

Share:

Talk to an expert

Have questions about this topic? Get in touch with our specialist.

Sales Representative
Grzegorz Gnych

Grzegorz Gnych

Sales Representative

Response within 24 hours
Free consultation
Individual approach

Providing your phone number will speed up contact.

Want to Reduce IT Risk and Costs?

Book a free consultation - we respond within 24h

Response in 24h Free quote No obligations

Or download free guide:

Download NIS2 Checklist