A practical guide for implementing SBOM generation, artifact signing, and provenance tracking in enterprise environments, aligned with Executive Order 14028 requirements.

Introduction

Executive Order 14028 (May 2021) mandates that federal agencies and their software suppliers implement software supply chain security measures, including:

  • Software Bill of Materials (SBOM) generation
  • Artifact signing and provenance verification
  • Secure software development practices

The urgency of these requirements was underscored by high-profile supply chain attacks:

  • SolarWinds (2020): Compromised build system affected 18,000+ organizations including federal agencies
  • Log4Shell (2021): CVE-2021-44228 exposed the challenge of identifying affected components across enterprise software portfolios
  • Codecov (2021): CI/CD pipeline compromise demonstrated supply chain attack vectors

This article provides a hands-on implementation guide based on real-world enterprise deployments in healthcare, financial services, and telecommunications sectors.


What is an SBOM?

An SBOM is a formal, machine-readable inventory of software components and dependencies. Think of it as a “nutritional label” for software — it lists every ingredient (library, framework, dependency) that goes into your application.

Key SBOM Formats

FormatStandard BodyStrengths
SPDXLinux FoundationISO/IEC 5962:2021 standard, comprehensive license tracking
CycloneDXOWASPSecurity-focused, vulnerability correlation, lightweight
SWID TagsISO/IEC 19770-2Enterprise asset management integration

NTIA Minimum Elements

Per NTIA guidance, an SBOM must include:

  1. Supplier Name — Entity that creates, defines, and identifies components
  2. Component Name — Designation assigned to a unit of software
  3. Version of the Component — Identifier used by supplier to specify a change
  4. Other Unique Identifiers — Other identifiers used to identify a component (PURL, CPE)
  5. Dependency Relationship — Characterizing the relationship (e.g., X includes Y)
  6. Author of SBOM Data — Entity that creates the SBOM data
  7. Timestamp — Record of the date and time of the SBOM data assembly

Why SBOMs Matter for Critical Infrastructure

The Log4Shell Case Study

When CVE-2021-44228 (Log4Shell) was disclosed in December 2021, organizations faced a critical question: “Where in our software portfolio is Log4j used?”

Organizations with SBOMs could:

  • Query their SBOM database within minutes
  • Identify affected applications, containers, and servers
  • Prioritize patching based on exposure and criticality

Organizations without SBOMs had to:

  • Manually scan thousands of applications
  • Search through dependency trees of unknown depth
  • Spend weeks identifying exposure

Bottom line: SBOMs transform incident response from days/weeks to minutes/hours.

Federal Mandate Timeline

DateMilestone
May 2021EO 14028 signed
November 2021NIST defines “critical software”
September 2022OMB M-22-18 requires attestation from software producers
2023-2024Federal agencies begin requiring SBOMs from vendors
December 2024CMMC 2.0 effective — supply chain security mandatory for DoD contractors

Implementation Architecture

Pipeline Overview

┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│   BUILD     │───▶│    SCAN     │───▶│    SIGN     │───▶│   PUBLISH   │───▶│   DEPLOY    │
│             │    │             │    │             │    │             │    │             │
│ Generate    │    │ Vuln scan   │    │ Cosign/     │    │ Store SBOM  │    │ Verify      │
│ SBOM (Syft) │    │ (Grype)     │    │ Sigstore    │    │ + artifact  │    │ signatures  │
└─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘    └─────────────┘

Components

StageToolPurpose
GenerateSyftCreate SBOM from container images, filesystems
ScanGrypeVulnerability scanning against SBOM
SignCosignKeyless signing via Sigstore
StoreOCI Registry / ArtifactoryArtifact + SBOM storage with attestations
VerifyCosign / KyvernoAdmission-time signature verification

Hands-On Implementation

Step 1: SBOM Generation with Syft

Install Syft

# macOS/Linux
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin

# Verify installation
syft version

Generate SBOM from Container Image

# CycloneDX JSON format (recommended for security use cases)
syft myregistry.azurecr.io/myapp:v1.2.3 -o cyclonedx-json > sbom.json

# SPDX format (for license compliance)
syft myregistry.azurecr.io/myapp:v1.2.3 -o spdx-json > sbom-spdx.json

# View in human-readable table
syft myregistry.azurecr.io/myapp:v1.2.3 -o table

GitHub Actions Integration

name: Build and Generate SBOM

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Container Image
        run: docker build -t ${{ env.IMAGE_NAME }}:${{ github.sha }} .

      - name: Generate SBOM
        uses: anchore/sbom-action@v0
        with:
          image: ${{ env.IMAGE_NAME }}:${{ github.sha }}
          format: cyclonedx-json
          output-file: sbom.cyclonedx.json

      - name: Upload SBOM as Artifact
        uses: actions/upload-artifact@v4
        with:
          name: sbom
          path: sbom.cyclonedx.json

Step 2: Vulnerability Scanning with Grype

Install Grype

curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

Scan SBOM for Vulnerabilities

# Basic scan
grype sbom:sbom.cyclonedx.json

# Fail on high/critical vulnerabilities (for CI/CD gates)
grype sbom:sbom.cyclonedx.json --fail-on high

# Output as JSON for further processing
grype sbom:sbom.cyclonedx.json -o json > vulnerabilities.json

CI/CD Gate Example

- name: Scan SBOM for Vulnerabilities
  run: |
    grype sbom:sbom.cyclonedx.json --fail-on critical
  continue-on-error: false

Step 3: Artifact Signing with Cosign

Cosign enables cryptographic signing of container images and attestations, providing provenance verification.

Install Cosign

# macOS
brew install cosign

# Linux
curl -O -L https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
chmod +x cosign-linux-amd64
mv cosign-linux-amd64 /usr/local/bin/cosign

Keyless signing uses Sigstore’s Fulcio CA and Rekor transparency log — no key management required.

# Sign the container image (keyless via OIDC)
cosign sign $IMAGE_NAME:$TAG

# Attach SBOM to the image
cosign attach sbom --sbom sbom.cyclonedx.json $IMAGE_NAME:$TAG

# Create and sign an SBOM attestation
cosign attest --predicate sbom.cyclonedx.json --type cyclonedx $IMAGE_NAME:$TAG

Key-Based Signing (Air-Gapped Environments)

# Generate key pair
cosign generate-key-pair

# Sign with private key
cosign sign --key cosign.key $IMAGE_NAME:$TAG

# Verify with public key
cosign verify --key cosign.pub $IMAGE_NAME:$TAG

Step 4: Complete Azure DevOps Pipeline

trigger:
  branches:
    include:
      - main
      - release/*

variables:
  imageName: 'myregistry.azurecr.io/myapp'
  tag: '$(Build.BuildId)'

stages:
  - stage: Build
    displayName: 'Build and Scan'
    jobs:
      - job: BuildJob
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - task: Docker@2
            displayName: 'Build Container Image'
            inputs:
              containerRegistry: 'AzureContainerRegistry'
              repository: 'myapp'
              command: 'build'
              Dockerfile: '**/Dockerfile'
              tags: '$(tag)'

          - script: |
              curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
              syft $(imageName):$(tag) -o cyclonedx-json > $(Build.ArtifactStagingDirectory)/sbom.json
            displayName: 'Generate SBOM'

          - script: |
              curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
              grype sbom:$(Build.ArtifactStagingDirectory)/sbom.json --fail-on critical
            displayName: 'Vulnerability Scan'

          - script: |
              curl -O -L https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
              chmod +x cosign-linux-amd64
              ./cosign-linux-amd64 sign --key $(COSIGN_PRIVATE_KEY) $(imageName):$(tag)
              ./cosign-linux-amd64 attest --key $(COSIGN_PRIVATE_KEY) --predicate $(Build.ArtifactStagingDirectory)/sbom.json --type cyclonedx $(imageName):$(tag)
            displayName: 'Sign Image and Attest SBOM'
            env:
              COSIGN_PRIVATE_KEY: $(CosignPrivateKey)
              COSIGN_PASSWORD: $(CosignPassword)

          - task: Docker@2
            displayName: 'Push to Registry'
            inputs:
              containerRegistry: 'AzureContainerRegistry'
              repository: 'myapp'
              command: 'push'
              tags: '$(tag)'

          - publish: $(Build.ArtifactStagingDirectory)/sbom.json
            artifact: sbom
            displayName: 'Publish SBOM Artifact'

Enterprise Considerations

Policy Enforcement with Kyverno

Enforce SBOM and signature requirements at Kubernetes admission time:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-signatures
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: verify-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "myregistry.azurecr.io/*"
          attestors:
            - count: 1
              entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
                      -----END PUBLIC KEY-----

Storage and Retention

RequirementImplementation
Centralized StorageStore SBOMs in artifact repository (JFrog Artifactory, AWS ECR, Azure ACR) alongside images
Retention PeriodRegulated industries: 7+ years (HIPAA, PCI DSS); align with software lifecycle
SearchabilityIndex SBOMs in a database (DependencyTrack, GUAC) for CVE impact queries
Access ControlRestrict SBOM access to security/compliance teams; avoid exposing dependency details publicly

Dependency-Track Integration

Dependency-Track provides continuous SBOM analysis:

# Upload SBOM to Dependency-Track via API
curl -X POST "https://dependencytrack.example.com/api/v1/bom" \
  -H "X-Api-Key: $DT_API_KEY" \
  -H "Content-Type: application/vnd.cyclonedx+json" \
  -d @sbom.cyclonedx.json

Alignment with Federal Standards

RequirementEO 14028 SectionImplementation
SBOM for critical softwareSection 4(e)Syft + CycloneDX
Provenance verificationSection 4(e)(ix)Cosign + Sigstore/Rekor
Vulnerability disclosureSection 4(d)Grype + OSV database
Integrity verificationSection 4(e)(iii)Image digests + attestations
Secure development attestationSection 4(e)(i)SLSA framework adoption

SLSA Framework Alignment

SLSA (Supply-chain Levels for Software Artifacts) provides a maturity model:

SLSA LevelRequirementsTools
Level 1Documentation of build processBuild scripts in version control
Level 2Tamper-resistant build serviceGitHub Actions, Azure Pipelines
Level 3Hardened build platform, provenanceSigstore, in-toto attestations
Level 4Hermetic, reproducible buildsBazel, Nix

Conclusion

Implementing SBOM in your CI/CD pipeline is no longer optional for organizations serving federal agencies or critical infrastructure sectors. The combination of:

  • Syft for SBOM generation
  • Grype for vulnerability scanning
  • Cosign for signing and attestation

…provides a foundation that can be adapted to your specific toolchain and compliance requirements.

Key Takeaways

  1. Start Now: Federal requirements are already in effect; don’t wait for an RFP to demand SBOMs
  2. Automate Everything: SBOMs must be generated on every build, not manually
  3. Sign and Attest: Unsigned SBOMs have limited value; cryptographic provenance is essential
  4. Store and Index: SBOMs are only useful if you can query them during incidents
  5. Enforce at Admission: Use Kyverno/Gatekeeper to block unsigned images

References


This article is part of a series on cloud security and DevSecOps best practices for regulated industries.