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:
- An auditor visits once per year or quarter
- The team prepares documentation for weeks
- The auditor verifies the state on the audit day
- 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:
- Principle — e.g., “All artifacts must have verifiable provenance”
- Objective — e.g., “Ensure supply chain integrity”
- Checklist — specific steps to execute
- Minimum evidence — what attestations must exist
- 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.
