Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
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: 1 addition & 1 deletion .github/scripts/verify-query-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ test "$(TARGET_KERNEL_FLAVORS=generic ./query-packages.sh list linux-kernel)" ==
# Check that when a package has multiple dependencies they are printed in the
# expected format.
test "$(TARGET_KERNEL_FLAVORS="generic aws" ./query-packages.sh single -o dependencies zfs)" == \
"linux-kernel-generic,linux-kernel-aws,delphix-rust,delphix-go,dwarves"
"linux-kernel-generic,linux-kernel-aws,delphix-rust,delphix-go,dwarves,syft,cyclonedx-cli"

# Check that the output from the appliance list contains zfs and
# delphix-platform packages. Note, we explicitly do not use grep -q here as it
Expand Down
24 changes: 24 additions & 0 deletions .github/scripts/verify-sbom-scan-flag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash -ex

set -o pipefail

cd "$(git rev-parse --show-toplevel)"

#
# Every package must explicitly set SBOM_DEEP_SCAN to "true" or "false" in
# its config.sh -- see docs on generate_sbom() in lib/common.sh. There is
# no default: a package that hasn't been classified yet must fail CI
# rather than silently ship without a CycloneDX sidecar or without an
# explicit decision that it doesn't need one.
#
unclassified=$(./query-packages.sh list -o name,sbom-deep-scan all |
awk -F'\t' '$2 == "none" { print $1 }')

if [[ -n "$unclassified" ]]; then
echo "The following packages have not set SBOM_DEEP_SCAN (\"true\" or" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add some context in this error that generally, 3rd-party forks of debian packages, or packages that are not included in a shipping product should set this to false, while 1st-party packages should set this to true so that their internal packaged components are included in the product's aggregate sbom.

"\"false\") in their config.sh:"
echo "$unclassified"
exit 1
fi

echo "All packages have classified SBOM_DEEP_SCAN"
5 changes: 5 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ jobs:
steps:
- uses: actions/checkout@v1
- run: ./.github/scripts/verify-query-packages.sh
verify-sbom-scan-flag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- run: ./.github/scripts/verify-sbom-scan-flag.sh
3 changes: 3 additions & 0 deletions buildpkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ stage build
logmust cd "$WORKDIR"
stage store_build_info

logmust cd "$WORKDIR"
stage generate_sbom

logmust cd "$WORKDIR"
stage post_build_checks

Expand Down
305 changes: 305 additions & 0 deletions docs/specs/2026-09-08-sbom-per-package-sidecar-design.md

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions lib/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,84 @@ function store_build_info() {
fi
}

#
# Generate a CycloneDX SBOM sidecar for each of this package's built
# .deb(s) by running Syft against it. Only packages that bundle
# third-party composition (jars, npm, wheels, Rust crates, ...) opt in
# via SBOM_DEEP_SCAN="true" in their config.sh -- everything else is
# left as a flat pkg:deb component by appliance-build's base chroot
# scan, so a deb scan here would add nothing. Each <deb-filename>.cdx.json
# is dropped in $WORKDIR/artifacts/ alongside the .deb it describes --
# a strict 1:1 mapping, no merging across a package's .deb(s) -- where
# it's picked up by the same S3 sync as every other build artifact, no
# separate upload path needed.
#
function generate_sbom() {
if [[ "$SBOM_DEEP_SCAN" != "true" ]]; then
return 0
fi

local debs=("$WORKDIR/artifacts/"*.deb)
if [[ ! -e "${debs[0]}" ]]; then
die "SBOM_DEEP_SCAN is set but no .deb was found in" \
"'$WORKDIR/artifacts'"
fi

#
# syft/cyclonedx-cli are build-host-only tooling (never shipped in
# any product package), fetched the same way any other linux-pkg
# build dependency is: declared in PACKAGE_DEPENDENCIES, populated
# into $DEPDIR by the "fetch_dependencies" stage, installed here.
# This mirrors appliance-build's build-ancillary-repository.sh,
# which installs the same two packages onto the appliance-build host
# for the same reason.
#
check_env DEPDIR
logmust install_pkgs "$DEPDIR"/syft/*.deb "$DEPDIR"/cyclonedx-cli/*.deb

#
# One sidecar per .deb, not per package: a package that emits more
# than one .deb (e.g. "zfs" splits into zfs-dkms, zfsutils-linux,
# etc.) gets one <deb-filename>.deb.cdx.json per .deb, each a
# standalone document scoped to that .deb alone. No merging across
# .debs -- keeps a strict 1:1 mapping between a .deb and its BOM,
# with the .deb's own filename as the common prefix.
#
local deb
for deb in "${debs[@]}"; do
local sbom_file deb_version
sbom_file="$WORKDIR/artifacts/$(basename "$deb").cdx.json"
#
# Read the version back out of the .deb itself, rather than
# relying on $PACKAGE_VERSION: by this point in the build,
# $PACKAGE_VERSION may no longer hold the final,
# revision-suffixed version set_changelog() wrote into the
# package (e.g. it's empty for packages that don't set it
# explicitly themselves, unlike syft/cyclonedx-cli's own
# config.sh). dpkg-deb reads the actual, authoritative
# version of the artifact being scanned.
#
deb_version="$(dpkg-deb -f "$deb" Version)"
#
# SYFT_FILE_METADATA_SELECTION=none suppresses Syft's default
# per-file "file" component (with SHA-1/SHA-256 hashes and the
# absolute build-workspace path baked in) -- noise that doesn't
# belong in a per-deb sidecar. Same reasoning as
# appliance-build's 95-generate-sbom.binary hook.
#
SYFT_FILE_METADATA_SELECTION=none logmust syft scan "$deb" \
--source-name "$PACKAGE" \
--source-version "$deb_version" \
-o "cyclonedx-json@1.6=$sbom_file"

logmust cyclonedx-cli validate \
--input-file "$sbom_file" \
--input-format json \
--input-version v1_6 \
--fail-on-errors
done
}

function set_secret_build_args() {
_SECRET_BUILD_ARGS=()

Expand Down
1 change: 1 addition & 0 deletions packages/bcc/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/bcc.git"
SBOM_DEEP_SCAN="false"

UPSTREAM_GIT_URL=https://github.com/iovisor/bcc.git
UPSTREAM_GIT_BRANCH=master
Expand Down
1 change: 1 addition & 0 deletions packages/challenge-response/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/challenge-response.git"
SBOM_DEEP_SCAN="false"

function prepare() {
install_build_deps_from_control_file
Expand Down
1 change: 1 addition & 0 deletions packages/cloud-init/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/cloud-init.git"
SBOM_DEEP_SCAN="false"

UPSTREAM_SOURCE_PACKAGE=cloud-init

Expand Down
1 change: 1 addition & 0 deletions packages/connstat/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/connstat.git"
SBOM_DEEP_SCAN="false"
PACKAGE_DEPENDENCIES="@linux-kernel dwarves"

function prepare() {
Expand Down
8 changes: 8 additions & 0 deletions packages/containerized-masking/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/dms-core-gate.git"
#
PACKAGE_NEEDS_DOCKER="true"
MEND_SCAN_APPLICABLE="true"
SBOM_DEEP_SCAN="true"

#
# syft/cyclonedx-cli are build-host-only tooling needed by generate_sbom()
# (lib/common.sh) to scan this package's own .deb -- never shipped in the
# built package itself.
#
PACKAGE_DEPENDENCIES="syft cyclonedx-cli"
MEND_SCAN_IMAGES="'delphix-masking-proxy', 'delphix-masking-database', 'delphix-masking-app'"

SKIP_COPYRIGHTS_CHECK=true
Expand Down
1 change: 1 addition & 0 deletions packages/crash-python/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# shellcheck disable=SC2034
DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/crash-python.git"
SBOM_DEEP_SCAN="false"

function prepare() {
logmust install_build_deps_from_control_file
Expand Down
2 changes: 2 additions & 0 deletions packages/crypt-blowfish/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/crypt-blowfish.git"
SBOM_DEEP_SCAN="false"

SKIP_COPYRIGHTS_CHECK=true

function build() {
Expand Down
1 change: 1 addition & 0 deletions packages/cyclonedx-cli/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/cyclonedx-cli.git"
SBOM_DEEP_SCAN="false"

function build() {
logmust mkdir -p "$WORKDIR/repo"
Expand Down
1 change: 1 addition & 0 deletions packages/delphix-go/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/delphix-go.git"
SBOM_DEEP_SCAN="false"

function build() {
logmust mkdir -p "$WORKDIR/repo"
Expand Down
1 change: 1 addition & 0 deletions packages/delphix-kernel/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/delphix-kernel.git"
SBOM_DEEP_SCAN="false"
PACKAGE_DEPENDENCIES="@linux-kernel"

function prepare() {
Expand Down
1 change: 1 addition & 0 deletions packages/delphix-platform/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/delphix-platform.git"
SBOM_DEEP_SCAN="false"

function prepare() {
logmust cd "$WORKDIR/repo"
Expand Down
8 changes: 8 additions & 0 deletions packages/delphix-rust/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/delphix-rust.git"
SBOM_DEEP_SCAN="true"

#
# syft/cyclonedx-cli are build-host-only tooling needed by generate_sbom()
# (lib/common.sh) to scan this package's own .deb -- never shipped in the
# built package itself.
#
PACKAGE_DEPENDENCIES="syft cyclonedx-cli"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the default hook is used, then the package's config.sh should not have to declare any such dependencies. Those should be handled by linux-pkg's generic build dependencies that are installed prior.


function build() {
logmust mkdir -p "$WORKDIR/repo"
Expand Down
8 changes: 8 additions & 0 deletions packages/delphix-sso-app/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/saml-app.git"
MEND_SCAN_APPLICABLE="true"
MEND_SCAN_USING_SUDO="true"
SBOM_DEEP_SCAN="true"

#
# syft/cyclonedx-cli are build-host-only tooling needed by generate_sbom()
# (lib/common.sh) to scan this package's own .deb -- never shipped in the
# built package itself.
#
PACKAGE_DEPENDENCIES="syft cyclonedx-cli"

function prepare() {
logmust install_pkgs openjdk-17-jdk-headless:
Expand Down
2 changes: 2 additions & 0 deletions packages/docker-python-image/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/docker-python-image.git"
SBOM_DEEP_SCAN="false"

#
# debian/rules' override_dh_install runs 'docker pull' to fetch the python
# image it repackages, so the build needs a docker daemon. The build container
Expand Down
1 change: 1 addition & 0 deletions packages/drgn/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# shellcheck disable=SC2034
DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/drgn.git"
SBOM_DEEP_SCAN="false"
PACKAGE_DEPENDENCIES="libkdumpfile"

UPSTREAM_GIT_URL="https://github.com/osandov/drgn.git"
Expand Down
1 change: 1 addition & 0 deletions packages/dwarves/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/dwarves.git"
SBOM_DEEP_SCAN="false"

UPSTREAM_GIT_URL="https://github.com/acmel/dwarves.git"
UPSTREAM_GIT_BRANCH="master"
Expand Down
1 change: 1 addition & 0 deletions packages/fluentd-gems/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/fluentd-gems.git"
SBOM_DEEP_SCAN="false"

function build() {
logmust mkdir -p "$WORKDIR/repo"
Expand Down
1 change: 1 addition & 0 deletions packages/gdb-python/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# shellcheck disable=SC2034
DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/gdb-python.git"
SBOM_DEEP_SCAN="false"
PACKAGE_DEPENDENCIES="libkdumpfile"

function prepare() {
Expand Down
1 change: 1 addition & 0 deletions packages/grub2/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL=none
SBOM_DEEP_SCAN="false"
SKIP_COPYRIGHTS_CHECK=true

URI="s3://release-de-images/internal-artifacts/2025.3.0.1/1.0.53/input-artifacts/combined-packages/packages/grub2"
Expand Down
1 change: 1 addition & 0 deletions packages/host-jdks/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/host-jdks.git"
SBOM_DEEP_SCAN="false"

function build() {
logmust mkdir -p "$WORKDIR/repo"
Expand Down
1 change: 1 addition & 0 deletions packages/libkdumpfile/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

# shellcheck disable=SC2034
DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/libkdumpfile.git"
SBOM_DEEP_SCAN="false"

UPSTREAM_GIT_URL="https://codeberg.org/ptesarik/libkdumpfile.git"
UPSTREAM_GIT_BRANCH="tip"
Expand Down
3 changes: 3 additions & 0 deletions packages/linux-kernel-aws/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ default)
die "invalid linux-kernel package source '$linux_package_source'"
;;
esac

# shellcheck disable=SC2034
SBOM_DEEP_SCAN="false"
3 changes: 3 additions & 0 deletions packages/linux-kernel-azure/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ default)
die "invalid linux-kernel package source '$linux_package_source'"
;;
esac

# shellcheck disable=SC2034
SBOM_DEEP_SCAN="false"
3 changes: 3 additions & 0 deletions packages/linux-kernel-gcp/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ default)
die "invalid linux-kernel package source '$linux_package_source'"
;;
esac

# shellcheck disable=SC2034
SBOM_DEEP_SCAN="false"
3 changes: 3 additions & 0 deletions packages/linux-kernel-generic/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ default)
die "invalid linux-kernel package source '$linux_package_source'"
;;
esac

# shellcheck disable=SC2034
SBOM_DEEP_SCAN="false"
3 changes: 3 additions & 0 deletions packages/linux-kernel-oracle/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@ default)
die "invalid linux-kernel package source '$linux_package_source'"
;;
esac

# shellcheck disable=SC2034
SBOM_DEEP_SCAN="false"
1 change: 1 addition & 0 deletions packages/makedumpfile/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/makedumpfile.git"
SBOM_DEEP_SCAN="false"

UPSTREAM_SOURCE_PACKAGE="makedumpfile"

Expand Down
8 changes: 8 additions & 0 deletions packages/masking/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ source "$PWD/lib/common.sh"

DEFAULT_PACKAGE_GIT_URL="https://github.com/delphix/dms-core-gate.git"
MEND_SCAN_APPLICABLE="true"
SBOM_DEEP_SCAN="true"

#
# syft/cyclonedx-cli are build-host-only tooling needed by generate_sbom()
# (lib/common.sh) to scan this package's own .deb -- never shipped in the
# built package itself.
#
PACKAGE_DEPENDENCIES="syft cyclonedx-cli"

function prepare() {
logmust read_list "$WORKDIR/repo/packaging/build-dependencies"
Expand Down
1 change: 1 addition & 0 deletions packages/misc-debs/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# shellcheck disable=SC2034

DEFAULT_PACKAGE_GIT_URL=none
SBOM_DEEP_SCAN="false"
SKIP_COPYRIGHTS_CHECK=true

#
Expand Down
Loading