Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1b4611c
Add CNPG SBOM generator workflow
ardentperf-agent[bot] Sep 15, 2026
bb60322
Use cnpg-extensions SBOM generator image
ardentperf-agent[bot] Sep 15, 2026
9d994db
Use explicit CNPG Extensions generator image path
ardentperf-agent[bot] Sep 15, 2026
2ebef09
Allow manual SBOM generator publishing for tests
ardentperf-agent[bot] Sep 15, 2026
a4d4832
Remove local Act support from CI workflows
ardentperf-agent[bot] Sep 15, 2026
f37a184
Separate SBOM and extension build triggers
ardentperf-agent[bot] Sep 15, 2026
0e72b92
Add SBOM generator progress diagnostics
ardentperf-agent[bot] Sep 15, 2026
4f60d02
Preserve SBOM composer executable mode
ardentperf-agent[bot] Sep 15, 2026
22a8bfe
Identify SBOM generator builds by Git revision
ardentperf-agent[bot] Sep 15, 2026
0983fb7
Update pinned SBOM generator image digest
ardentperf-agent[bot] Sep 15, 2026
8217f71
Clarify ScanCode total license chunk count
ardentperf-agent[bot] Sep 15, 2026
dbc9517
Report completed ScanCode license chunks
ardentperf-agent[bot] Sep 15, 2026
0dcd849
Report ScanCode progress every hundred chunks
ardentperf-agent[bot] Sep 15, 2026
13c3a26
Revert "Report ScanCode progress every hundred chunks"
ardentperf-agent[bot] Sep 15, 2026
ee2a5cc
Report ScanCode progress every ten seconds
ardentperf-agent[bot] Sep 15, 2026
b9965f4
Use one ten-second scanner progress interval
ardentperf-agent[bot] Sep 15, 2026
553a6e9
Serialize BuildKit operations to reduce SBOM memory pressure
ardentperf-agent[bot] Sep 15, 2026
7cf86cc
Update pinned SBOM generator to latest image
ardentperf-agent[bot] Sep 15, 2026
478fcc1
Simplify ScanCode logging to per-run timing
ardentperf-agent[bot] Sep 15, 2026
ff514a7
Log each completed ScanCode license chunk
ardentperf-agent[bot] Sep 15, 2026
4276672
Pass ScanCode output directly to build logs
ardentperf-agent[bot] Sep 15, 2026
101874a
Remove redundant ScanCode wrapper status messages
ardentperf-agent[bot] Sep 15, 2026
7b4ac37
Update pinned SBOM generator to latest image
ardentperf-agent[bot] Sep 15, 2026
07a6c3c
Restore upstream GitHub Action pins after rebase
ardentperf-agent[bot] Sep 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/bake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
paths-ignore:
- '.github/workflows/pgrx.yml'
- '.github/workflows/pgrx_targets.yml'
- '.github/workflows/sbom-generator.yml'
- 'sbom-generator/**'
workflow_dispatch:
inputs:
extension_name:
Expand Down
15 changes: 15 additions & 0 deletions .github/workflows/bake_targets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ jobs:

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4
with:
# Run SBOM generators sequentially to reduce peak runner memory use.
buildkitd-config-inline: |
[worker.oci]
max-parallelism = 1

- name: Expose builder stage to SBOM generator
env:
EXTENSION: ${{ inputs.extension_name }}
run: |
sed -i '2i ARG BUILDKIT_SBOM_SCAN_STAGE=builder' "$EXTENSION/Dockerfile"

- name: Build and push
uses: docker/bake-action@018cb6412ab401ebaa809aa5f85966b74628600f # v7
Expand All @@ -54,7 +65,11 @@ jobs:
environment: testing
registry: ghcr.io/${{ github.repository_owner }}
revision: ${{ github.sha }}
# renovate: datasource=docker depName=ghcr.io/cnpg-extensions/cnpg-sbom-generator
sbom_generator: ghcr.io/cnpg-extensions/cnpg-sbom-generator:latest@sha256:38605482cdeb890e015a0d0e49edd473ecb483a2c0f075f3550e4470f247861e
with:
# Use the checkout so Bake sees the injected Dockerfile declaration.
source: .
files: ./docker-bake.hcl,./${{ inputs.extension_name }}/metadata.hcl
push: true

Expand Down
61 changes: 50 additions & 11 deletions .github/workflows/sbom-generator.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,73 @@
name: Build SBOM generator (stub)
name: Build and publish SBOM generator

on:
push:
branches: [main]
paths:
- 'sbom-generator/**'
- '.github/workflows/sbom-generator.yml'
pull_request:
paths:
- 'sbom-generator/**'
- '.github/workflows/sbom-generator.yml'
workflow_dispatch:
inputs:
publish:
description: "Publish the generator image to GHCR (manual testing only)"
required: false
default: false
type: boolean

permissions: {}

concurrency:
group: sbom-generator-${{ github.ref }}
cancel-in-progress: false

jobs:
build:
name: Build SBOM generator stub
runs-on: ubuntu-24.04
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
persist-credentials: false

- name: Run tests
run: python3 -m unittest discover -s sbom-generator/tests -p 'test_*.py'

- name: Set up QEMU
uses: docker/setup-qemu-action@99012661954931238ded8c8b007157a8430204e1 # v4
with:
platforms: linux/arm64

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4

- name: Build generator stub
- name: Log in to GHCR
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.publish == true) }}
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build generator
env:
IMAGE: cnpg-sbom-generator:stub-${{ github.sha }}
EVENT_NAME: ${{ github.event_name }}
PUBLISH: ${{ inputs.publish }}
run: |
image="ghcr.io/cnpg-extensions/cnpg-sbom-generator"
options=()
if [[ "$EVENT_NAME" == push || "$PUBLISH" == true ]]; then options+=(--push); fi
docker buildx build \
--load \
--tag "$IMAGE" \
-f- . <<'DOCKERFILE'
FROM scratch
LABEL org.opencontainers.image.title="cnpg-sbom-generator"
LABEL org.opencontainers.image.description="Workflow-dispatch stub build"
DOCKERFILE
--platform linux/amd64,linux/arm64 \
--build-arg "SBOM_GENERATOR_REVISION=${GITHUB_SHA}" \
--label "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \
--tag "$image:latest" \
--tag "$image:sha-${GITHUB_SHA}" \
"${options[@]}" \
sbom-generator
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
*.so
*.dylib

# Python test and bytecode caches
__pycache__/
*.py[cod]

# Mac
.DS_Store

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,14 @@ docker buildx imagetools inspect <image> --raw | jq '.annotations'
skopeo inspect docker://<image> | jq '.Labels'
```

## SBOMs and authenticity

Published images carry platform-specific BuildKit SPDX and provenance
attestations. See the [SBOM and authenticity guide](./sbom-generator/README.md)
for digest-pinned Cosign verification, Buildx extraction, platform-specific
Trivy scanning, and the distinction between payload inventory and direct image
scans.

## Image catalogs

To simplify the deployment of PostgreSQL extensions, this project automatically
Expand Down
8 changes: 5 additions & 3 deletions docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ variable "revision" {
}

fullname = ( environment == "testing") ? "${registry}/${metadata.image_name}-testing" : "${registry}/${metadata.image_name}"
variable "sbom_generator" {
default = ""
}
now = timestamp()
authors = "The CNPG Extensions Contributors"
url = "https://github.com/cnpg-extensions/postgres-extensions-containers"
Expand Down Expand Up @@ -48,10 +51,9 @@ target "default" {
output = [
"type=image,oci-mediatypes=true,oci-artifact=true",
]
attest = [
attest = concat([
"type=provenance,mode=max",
"type=sbom"
]
], sbom_generator == "" ? ["type=sbom"] : ["type=sbom,generator=${sbom_generator}"])
annotations = [
"index,manifest:org.opencontainers.image.created=${now}",
"index,manifest:org.opencontainers.image.url=${url}",
Expand Down
75 changes: 75 additions & 0 deletions examples/trivy-sbom-examples.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Trivy SBOM example
#
# This report was generated from the SPDX document extracted from the local
# OCI attestation for pgagent bookworm. Long Debian copyright files were split
# at License: sections before ScanCode ran. The image was built locally with
# BuildKit and pushed to a local registry. GitHub OIDC/cosign attestation
# verification is omitted because it requires a hosted GitHub runner.

$ docker buildx imagetools inspect 127.0.0.1:5000/pgagent-testing:4.2.3-18-bookworm@sha256:ea4735334c2f494b45b4ba50ac44f66bf55e6e4af56599862e6062341e5eb54e --format '{{ json .SBOM.SPDX }}' > /tmp/pgagent-bookworm-amd64.spdx.json
$ docker run --rm -v /tmp:/work aquasec/trivy:0.74.0 sbom --scanners vuln,license --no-progress --skip-version-check /work/pgagent-bookworm-amd64.spdx.json
2026-09-15T04:04:17Z INFO [vulndb] Need to update DB
2026-09-15T04:04:17Z INFO [vulndb] Downloading vulnerability DB...
2026-09-15T04:04:17Z INFO [vulndb] Downloading artifact... repo="mirror.gcr.io/aquasec/trivy-db:2"
2026-09-15T04:04:30Z INFO [vulndb] Artifact successfully downloaded repo="mirror.gcr.io/aquasec/trivy-db:2"
2026-09-15T04:04:30Z INFO [vuln] Vulnerability scanning is enabled
2026-09-15T04:04:30Z INFO [license] License scanning is enabled
2026-09-15T04:04:30Z INFO Detected SBOM format format="spdx-json"
2026-09-15T04:04:30Z INFO Detected OS family="debian" version="12.15"
2026-09-15T04:04:30Z INFO [debian] Detecting vulnerabilities... os_version="12" pkg_num=3
2026-09-15T04:04:30Z INFO Number of language-specific files num=0

Report Summary

┌───────────────────────────────────────────────────────┬────────┬─────────────────┬──────────┐
│ Target │ Type │ Vulnerabilities │ Licenses │
├───────────────────────────────────────────────────────┼────────┼─────────────────┼──────────┤
│ /work/pgagent-bookworm-amd64.spdx.json (debian 12.15) │ debian │ 1 │ - │
├───────────────────────────────────────────────────────┼────────┼─────────────────┼──────────┤
│ OS Packages │ - │ - │ 3 │
└───────────────────────────────────────────────────────┴────────┴─────────────────┴──────────┘
Legend:
- '-': Not scanned
- '0': Clean (no security findings detected)


/work/pgagent-bookworm-amd64.spdx.json (debian 12.15)
=====================================================
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)

┌─────────┬───────────────┬──────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Status │ Installed Version │ Fixed Version │ Title │
├─────────┼───────────────┼──────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ pgagent │ CVE-2025-0218 │ HIGH │ affected │ 4.2.3-5.pgdg12+1 │ │ When batch jobs are executed by pgAgent, a script is created │
│ │ │ │ │ │ │ in... │
│ │ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2025-0218 │
└─────────┴───────────────┴──────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────────┘

OS Packages (license)
=====================
Total: 3 (UNKNOWN: 3, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)

┌───────────────────────────┬──────────────────────────────────────────────────────────────┬────────────────┬──────────┐
│ Package │ License │ Classification │ Severity │
├───────────────────────────┼──────────────────────────────────────────────────────────────┼────────────────┼──────────┤
│ libboost-filesystem1.74.0 │ Apache-2.0 AND LicenseRef-BSD2 AND LicenseRef-BSD3-DEShaw │ unknown │ UNKNOWN │
│ │ AND LicenseRef-BSD3-Google AND BSL-1.0 AND │ │ │
│ │ LicenseRef-Caramel AND LicenseRef-CrystalClear AND │ │ │
│ │ LicenseRef-HP AND Jam AND LicenseRef-Kempf AND MIT AND │ │ │
│ │ LicenseRef-NIST AND LicenseRef-OldBoost1 AND │ │ │
│ │ LicenseRef-OldBoost2 AND LicenseRef-OldBoost3 AND │ │ │
│ │ LicenseRef-Python AND LicenseRef-SGI AND LicenseRef-Spencer │ │ │
│ │ AND Zlib │ │ │
├───────────────────────────┤ │ │ │
│ libboost-thread1.74.0 │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
├───────────────────────────┼──────────────────────────────────────────────────────────────┤ │ │
│ pgagent │ LicenseRef-scancode-unknown-license-reference AND PostgreSQL │ │ │
└───────────────────────────┴──────────────────────────────────────────────────────────────┴────────────────┴──────────┘
33 changes: 33 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,39 @@
"matchStrings": [
"\\/\\/\\s+renovate: datasource=(?<datasource>[a-z-.]+?) depName=(?<depName>[^\\s]+?)(?: (?:packageName)=(?<packageName>[^\\s]+?))?(?: versioning=(?<versioning>[^\\s]+?))\\s+\\/\\/\\s+\\+default=[\\\"']?[^:]+?:(?<currentValue>[^@]+?)(@(?<currentDigest>sha256:[0-9a-f]+))?[\"']?\\s"
]
},
{
"description": "updates the SBOM generator base image",
"customType": "regex",
"managerFilePatterns": [
"sbom-generator/Dockerfile"
],
"matchStrings": [
"#\\s*renovate: datasource=(?<datasource>[^\\s]+) depName=(?<depName>[^\\s]+)(?: packageName=(?<packageName>[^\\s]+))?(?: versioning=(?<versioning>[^\\s]+))?\\s+FROM\\s+(?:[a-zA-Z0-9._/-]+:)?(?<currentValue>[^@\\s]+)(?:@(?<currentDigest>sha256:[0-9a-f]+))?"
]
},
{
"description": "updates the SBOM generator Dockerfile frontend",
"customType": "regex",
"managerFilePatterns": [
"sbom-generator/Dockerfile"
],
"matchStrings": [
"# syntax=docker/dockerfile:(?<currentValue>[^\\s]+)"
],
"depNameTemplate": "docker/dockerfile",
"datasourceTemplate": "docker",
"versioningTemplate": "docker"
},
{
"description": "updates the SBOM generator tool versions",
"customType": "regex",
"managerFilePatterns": [
"sbom-generator/Dockerfile"
],
"matchStrings": [
"#\\s*renovate: datasource=(?<datasource>[^\\s]+) depName=(?<depName>[^\\s]+)(?: versioning=(?<versioning>[^\\s]+))?\\s+ARG [A-Z0-9_]+_VERSION=(?<currentValue>[^\\s]+)"
]
}
],
"packageRules": [
Expand Down
32 changes: 32 additions & 0 deletions sbom-generator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# syntax=docker/dockerfile:1.7

# Python 3.14 is the newest version supported by the pinned ScanCode 32.5.0.
# Move to a newer Python as soon as ScanCode supports it; keep this aligned with SCANCODE_VERSION.
# https://github.com/aboutcode-org/scancode-toolkit/releases/tag/v32.5.0
# renovate: datasource=docker depName=python packageName=library/python versioning=docker
FROM python:3.14-slim-bookworm

ARG TARGETARCH
# renovate: datasource=github-releases depName=anchore/syft versioning=semver
ARG SYFT_VERSION=1.51.1
# renovate: datasource=pypi depName=scancode-toolkit versioning=pep440
ARG SCANCODE_VERSION=32.5.0

RUN apt-get update \
&& apt-get install --no-install-recommends -y ca-certificates curl gcc g++ libxml2-dev libxslt1-dev pkg-config \
&& rm -rf /var/lib/apt/lists/* \
&& curl --fail --silent --show-error --location \
"https://github.com/anchore/syft/releases/download/v${SYFT_VERSION}/syft_${SYFT_VERSION}_linux_${TARGETARCH}.tar.gz" \
| tar -xz -C /usr/local/bin syft \
&& python -m pip install --no-cache-dir "scancode-toolkit==${SCANCODE_VERSION}" \
&& syft version

WORKDIR /opt/cnpg-sbom-generator
COPY compose.py generator.py hooks.py ./

ARG SBOM_GENERATOR_REVISION=unknown
ENV SBOM_GENERATOR_REVISION=${SBOM_GENERATOR_REVISION}
LABEL org.opencontainers.image.revision=${SBOM_GENERATOR_REVISION}

ENV PYTHONUNBUFFERED=1
ENTRYPOINT ["python3", "/opt/cnpg-sbom-generator/generator.py"]
Loading
Loading