Pipeline Integrity

Pipeline Bill of Materials

An SBOM tells you what is inside the artifact. A PBOM tells you how it got there.

Cryptographic pipeline lineage across GitHub Actions and Kargo. Zero developer friction. Complete chain-of-custody from commit to production.

3
Lineage Phases
14
Build Tools Detected
0s
Developer Friction
5
CLI Commands

// DATA_MODEL

Three-Phase Lineage

PBOM separates artifact provenance into three distinct temporal phases, each capturing a different aspect of the pipeline lineage.

A

Source & Build

Captured during GitHub Actions workflow execution. Records source code identity and build environment.

  • Repository, commit SHA, branch, author
  • Workflow run ID, name, trigger event
  • Runner OS, architecture, self-hosted flag
  • Tool versions (14 build tools)
  • Secrets accessed (names only)
B

Artifacts & Security

Captured after build succeeds. Records what was produced and its security posture at creation time.

  • Artifact name, type, SHA256 digest
  • Registry URI and tags
  • SLSA provenance level (0–4)
  • Vulnerability snapshot (C/H/M/L)
  • Builder ID and attestation URI
C

Promotion

Captured when artifacts are promoted through deployment stages via Kargo GitOps.

  • Kargo Freight ID
  • Target stage (dev, staging, prod)
  • Who promoted and when
  • Co-deployed services snapshot
  • Full environment context
Commit SHA Workflow Run Image Digest Kargo Stage Production

// HOW_IT_WORKS

Zero-Touch Collection

PBOM runs as a Required Workflow at the org level. Developers never see it, never configure it, never wait for it.

01

Deploy

Install the PBOM Required Workflow at the org level. Runs automatically on every push and PR across all repos.

02

Collect

The workflow captures source and build identity from GITHUB_* environment variables. No code checkout, no interference.

03

Enrich

A webhook listener enriches the PBOM with runner details, tool versions, artifact digests, and vulnerability data.

04

Attest

The final PBOM is stored as an OCI artifact referrer, cryptographically linked to the container image it describes.

Developer Impact: Zero

Does not check out repo source. Does not interfere with the developer's build. Never blocks a merge (continue-on-error: true). Adds ~10 seconds to the checks list.

// CLI_REFERENCE

5 CLI Commands

Generate, validate, inspect, push, and version. Built with Go and Cobra.

pbom generate

Production Ready

Generate a PBOM from the current GitHub Actions environment. Reads GITHUB_* env vars to produce a lineage document with zero configuration.

# Generate and write to file
pbom generate -o pbom.json
# Generate to stdout
pbom generate
Flags: -o, --output <file> — Write PBOM to file (default: stdout)

pbom validate <file>

Production Ready

Validate a PBOM document for schema correctness. Checks required fields, commit SHA format (40-char hex), and artifact digest format (sha256: + 64 hex).

pbom validate pbom.json
valid

pbom inspect <file>

Production Ready

Display pipeline lineage in a human-readable format. Shows source, build, artifacts, and promotion data in structured sections.

$ pbom inspect pbom.json
PBOM f47ac10b-58cc-4372-a567-0e02b2c3d479
SOURCE
Repositoryacme-corp/payments-service
Commita1b2c3d4e5f6...a1b2
Branchmain
BUILD
WorkflowCI (7890123456)
Triggerpush
Actorjane.doe
Statussuccess
Flags: --json — Output raw JSON instead of formatted summary

pbom push <file> <artifact-ref>

Coming Soon

Push a PBOM to an OCI registry as a referrer artifact. Links the lineage document to the container image it describes using the OCI 1.1 Referrers API.

pbom push pbom.json ghcr.io/acme-corp/my-app@sha256:abc123...

pbom version

Print PBOM CLI and schema version.

$ pbom version
pbom dev (schema 1.0.0)

// TOOL_DETECTION

14 Build Tools Detected

PBOM probes the build runner's PATH for known tools and records their exact versions. Covers the most common build ecosystems.

Go
go version
Node.js
node --version
Python
python3 --version
Java
java -version
Docker
docker version
kubectl
kubectl version
Helm
helm version
ko
ko version
Cargo
cargo --version
rustc
rustc --version
.NET
dotnet --version
Gradle
gradle --version
Maven
mvn --version
npm
npm --version

// DOCUMENT_SCHEMA

PBOM Document Structure

JSON Schema Draft 2020-12. Every field is typed and validated. The schema is the contract.

Root Fields

Required: pbom_version, id, timestamp, source, build

pbom_versionconst: "1.0.0"
idUUID v4
timestampISO 8601 UTC
sourceobject (required)
buildobject (required)
artifactsarray (optional)
promotionobject (optional)

Source Object

Required: repository, commit_sha

repository"acme-corp/payments-service"
commit_sha40-char hex (required)
branchstring (optional)
reffull git ref (optional)
authorstring (optional)

Build Object

Required: workflow_run_id, workflow_name, actor, status

workflow_run_idGHA run ID (required)
workflow_name"CI", "Release" (required)
triggerpush | pull_request | schedule | ...
actorGitHub user (required)
statussuccess | failure | cancelled
runner{ os, arch, name, self_hosted }
tool_versions{ "go": "1.22.4", ... }
secrets_accessed["GHCR_TOKEN", ...] (names only)

Artifact Object

Required: name, type, digest

nameartifact name (required)
typecontainer-image | binary | package | ...
digestsha256:<64 hex chars>
uriregistry URI (optional)
tags["v1.0.0", "latest"]
provenance{ slsa_level, builder_id }
vulnerabilities{ scanner, critical, high, ... }
pbom.json
{
  "pbom_version": "1.0.0",
  "id": "f47ac10b-58cc-4372...",
  "timestamp": "2026-01-28T14:30:00Z",
  "source": {
    "repository": "acme-corp/payments-service",
    "commit_sha": "a1b2c3d4e5f6...a1b2",
    "branch": "main",
    "author": "jane.doe"
  },
  "build": {
    "workflow_run_id": "7890123456",
    "workflow_name": "CI",
    "trigger": "push",
    "actor": "jane.doe",
    "status": "success",
    "tool_versions": {
      "go": "1.22.4",
      "ko": "0.15.2"
    }
  },
  "artifacts": [{
    "name": "payments-service",
    "type": "container-image",
    "digest": "sha256:9f86d081...",
    "vulnerabilities": {
      "scanner": "trivy",
      "critical": 0,
      "high": 1
    }
  }]
}

// DEPLOYMENT

Deploy as a Required Workflow

Install once at the org level. Every repo gets pipeline lineage automatically.

Required Workflow
name: PBOM Collector
on:
push: { branches: [main, master] }
pull_request:
permissions:
contents: read
actions: read
jobs:
collect:
runs-on: ubuntu-latest
continue-on-error: true
steps:
- # Install PBOM CLI
- run: pbom generate -o pbom.json
- run: pbom inspect pbom.json
- uses: actions/upload-artifact@v4
with:
name: pbom-${{ github.run_id }}
path: pbom.json
retention-days: 90

Setup in 3 Steps

01

Add to central repo

Copy the PBOM Collector workflow to your org's .github repository or platform-workflows repo.

02

Enable as Required Workflow

Org Settings → Actions → Required Workflows → Add workflow. Select which repos to apply it to (all or subset).

03

Done

Every push and PR now generates a PBOM. Developers don't need to change anything. PBOMs are uploaded as artifacts with 90-day retention.

Collection Responsibility Split

Commit, branch, actor, refRequired Workflow
Run ID, workflow name, triggerRequired Workflow
Runner OS/arch, tool versionsWebhook Listener
Secrets accessedAudit Log API
Artifact digests, vulnerabilitiesWebhook Listener
Kargo freight / promotionKargo Controller

// SBOM_VS_PBOM

Why Both Matter

An SBOM lists ingredients. A PBOM verifies the kitchen. You need both for complete supply chain integrity.

SBOM PBOM
Question What's inside the artifact? How did the artifact get built?
Tracks Dependencies, licenses, CVEs Source, build env, runner, tools
Detects Known vulnerabilities in deps Compromised build environments
Prevents Shipping vulnerable libraries SolarWinds-style supply chain attacks
Standard CycloneDX, SPDX PBOM Schema v1.0.0 (JSON)

Stop trusting the pipeline blindly.

PBOM proves exactly which human, runner, and compiler produced every artifact. Forensic-grade lineage from commit to production.