name: inverse layout: true class: center, middle, inverse, title β€”

Not just ticking a box β˜‘οΈ

Establishing trust in artifacts with provenance πŸ”πŸ”—

Open Source Summit - North America 2025

Andrew McNamara β€’ Red Hat

Ralph Bean β€’ Red Hat

.footnote[πŸ”— slides: ralphbean.github.io/slides/oss-na/2025/provenance.html]


layout: false .left-column[ ## Meatspace Analogy ] .right-column[

When you buy something physical…

.large[ You get this information stamped on packaging or included in the box. ]

]


.left-column[ ## Meatspace Analogy ## Software Reality ] .right-column[

When you consume a software artifact in production…

.large[ Do you know its provenance? ]

.large[ We generally don’t get this with software today. ]

]


layout: false .left-column[ ## Meatspace Analogy ## Software Reality ## What is Provenance? ] .right-column[

What is provenance?

For software artifacts (containers, packages, binaries):

.foonote[ Generally, provenance is the origin of something. ]

]


.left-column[ ## Meatspace Analogy ## Software Reality ## What is Provenance? ## Threats ] .right-column[

.footnote[*from the β€œSupply-chain Levels for Software Artifacts” (SLSA) docs!]

]


.left-column[ ## Meatspace Analogy ## Software Reality ## What is Provenance? ## Threats ## Traditional Signing ] .right-column[

Traditional Software Signing is Limited

gpg --verify artifact.tar.gz.sig artifact.tar.gz

βœ… Identity: Who signed this?
❓ Context: What were they claiming when they signed it?

.large[ A signature just means β€œit’s good”

But good how? Good why? ]

]


template: inverse

πŸ“‹ Enter: Attestations


layout: false .left-column[ ## Attestations ] .right-column[

in-toto Attestation Framework

.large[ An attestation is an β€œI solemnly swearβ€¦β€œ statement ]

Instead of just β€œit’s signed” β†’ β€œhere’s exactly what happened”

]


layout: false .left-column[ ## Attestations ## sigstore & cosign ] .right-column[

cosign from the sigstore project

$ echo '{"hello": "world"}' > predicate.json

$ cosign attest \
    --type custom \
    --predicate predicate.json \
    quay.io/rbean/test:oss-na

$ cosign verify-attestation \
    --certificate-identity ralph.bean@gmail.com \
    --certificate-oidc-issuer https://github.com/login/oauth \
    quay.io/rbean/test:oss-na \
        | jq '.payload | @base64d | fromjson'

]

layout: false .left-column[ ## Attestations ## sigstore & cosign ## systems ] .right-column[

Compare systems that produce provenance

Β  πŸ™ GitHub πŸ¦‰ Witness 🐱 Tekton
Source βœ… Detailed βœ… Detailed βœ… Detailed
Parameters βœ… Detailed βœ… Detailed βœ… Detailed
Materials ❓ Unclear βœ… Detailed βœ… Detailed
Signature ❓ In build ❓ In build ⚠️ External

]


template: inverse

πŸ—οΈ Konflux: Our Project


layout: false .left-column[ ## Konflux ] .right-column[

: Secure Software Factory

.large[ Open source, cloud native software factory focused on supply chain security. ]

.footnote[ Each step creates verifiable evidence ]

]


layout: false .left-column[ ## Konflux ## Doing Stuff ] .right-column[

Stuff you can do

πŸ“Š Compliance & Auditing

πŸ” Incident Response

🧬 Evolve Posture

]


.left-column[ ## Konflux ## Doing Stuff ## Policy Gates ] .right-column[

conforma: Policy-Based Gating

deny contains result if {
  some required_task in _missing_tasks(current_required_tasks.tasks)

  # Don't report an error if a task is required now, but not in the future
  required_task in latest_required_tasks.tasks
  result := lib.result_helper_with_term(
    rego.metadata.chain(),
    [_format_missing(required_task, false)],
    required_task
  )
}

Machine-readable policies decide what gets released.

]


.left-column[ ## Konflux ## Doing Stuff ## Policy Gates ## Innovation (last slide) ] .right-column[

Enabling Safe Innovation

.large[ One way: Make insecure things impossible ]

.large[ Another way: Define what β€œgood” looks like ]

]


template: inverse

konflux is kool

Monday, June 23 (cdCon)

Lock the Chef in the Kitchen: Enabling Accurate SBOMs Via Hermetic Builds

Wednesday, June 24 (cdCon)

Who Are You Building For: Pipelines Have a Purpose

Wednesday, June 25 (OpenGovCon)

Building Trust Through Proactive Security - Key Parts of the Trusted Software Supply Chain

Thursday, June 26 (OpenSSF Community Day)

Who Are You Building For: Pipelines Have a Purpose


name: last-page template: inverse

πŸ”— Resources & Questions

Blog: How we use software provenance at Red Hat

sigstore project: sigstore.dev

in-toto Attestations: in-toto.io

SLSA Framework: slsa.dev

Conforma: conforma.dev

Try Konflux: konflux-ci.dev

slides: ralphbean.github.io/slides/oss-na/2025/provenance.html


name: inverse layout: true class: center, middle, inverse, title β€”

Thanks!

.footnote[Andrew McNamara β€’ Ralph Bean]

Appendix


layout: false .left-column[ ## GitHub ] .right-column[

GitHub Actions Provenance

jobs:
  build:
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: make build
      - uses: actions/attest-build-provenance@v1
        with:
          subject-path: './dist/app'

βœ… Source: Commit SHA, repo URL
βœ… Workflow: Workflow file, inputs
❓ Materials: Which actions?
❓ Data plane: Signature happens in the workflow

]

layout: false .left-column[ ## GitHub ] .right-column[

GitHub Actions Provenance

If there’s network, show:

IMAGE=quay.io/lucarval/festoji@sha256:b508f3da1ba56f258d72da91c8ce07950ced85f142d81974022f61211c4a445a
oras blob fetch "$IMAGE" --output - | \
    jq '.dsseEnvelope.payload | @base64d | fromjson '

βœ… Source: Commit SHA, repo URL
βœ… Workflow: Workflow file, inputs
❓ Materials: Which actions?
❓ Data plane: Signature happens in the workflow

]


.left-column[ ## GitHub ## Witness ] .right-column[

Witness Framework

witness run -s build -- make build
witness run -s test -- make test  
witness run -s deploy -- kubectl apply -f app.yaml

βœ… Source: Commit SHA, repo URL
βœ… Detailed task execution: How was it called
βœ… Detailed materials: What was used
❓ Data plane: Signature happens in the workflow

]

.footnote[or with a GitHub Action: https://github.com/testifysec/witness-demo]

.left-column[ ## GitHub ## Witness ] .right-column[

Witness Provenance

If there’s network, show:

GITOID=ea3c0279f13820dba07aafc8d215971f32f3053bb41743e88a00e669eec6c64f
curl -s https://archivista.testifysec.io/download/$GITOID -- | 
    jq '.payload | @base64d | fromjson '

βœ… Source: Commit SHA, repo URL
βœ… Detailed task execution: How was it called
βœ… Detailed materials: What was used
❓ Data plane: Signature happens in the workflow

]


.left-column[ ## GitHub ## Witness ## Tekton ] .right-column[

Tekton Chains Provenance

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  annotations:
    chains.tekton.dev/signed: "true"
spec:
  taskRef:
    name: git-clone
  params:
    - name: url
      value: https://github.com/example/repo

βœ… Source: Commit SHA, repo URL
βœ… Detailed task execution: How was it called
βœ… Detailed materials: What was used
βœ… Control plane: Payload doesn’t sign itself

]


.left-column[ ## GitHub ## Witness ## Tekton ] .right-column[

Tekton Chains Provenance

If there’s network, show:

IMAGE=quay.io/bootc-devel/fedora-bootc-rawhide-standard:20250605-110837
cosign download attestation $IMAGE  2> /dev/null | \
    jq '.payload | @base64d | fromjson '

βœ… Source: Commit SHA, repo URL
βœ… Detailed task execution: How was it called
βœ… Detailed materials: What was used
βœ… Control plane: Payload doesn’t sign itself

]