From 85bcc0c6d1acf276d061de705420c926f33e1851 Mon Sep 17 00:00:00 2001 From: chen21019 <19357113+chen21019@users.noreply.github.com> Date: Sun, 25 Oct 2026 06:44:23 +0800 Subject: [PATCH 1/2] Consume verified Ubuntu security backports in the final runtime --- .../collect-ubuntu-backport-evidence.sh | 34 +++++++++++++++++++ .github/workflows/security-build.yml | 18 +++++++--- README.md | 11 +++--- package/Dockerfile | 18 ++++++++++ 4 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 .github/scripts/collect-ubuntu-backport-evidence.sh diff --git a/.github/scripts/collect-ubuntu-backport-evidence.sh b/.github/scripts/collect-ubuntu-backport-evidence.sh new file mode 100644 index 0000000..6896641 --- /dev/null +++ b/.github/scripts/collect-ubuntu-backport-evidence.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Only read the exact consumer and immutable bundle; execute its guard on the runner. +set -euo pipefail +test "$#" -eq 3 +image=$1 +sbom=$2 +evidence=$3 +bundle_image='ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' +bundle_digest=${bundle_image##*@} +[[ "$bundle_digest" =~ ^sha256:[0-9a-f]{64}$ ]] +test -s "$sbom" +mkdir -p "$evidence" +scratch=$(mktemp -d) +consumer= +bundle= +cleanup() { + if [[ -n "$consumer" ]]; then docker rm "$consumer" >/dev/null 2>&1 || true; fi + if [[ -n "$bundle" ]]; then docker rm "$bundle" >/dev/null 2>&1 || true; fi + rm -rf -- "$scratch" +} +trap cleanup EXIT +consumer=$(docker create --entrypoint /bin/true "$image") +docker cp "$consumer:/usr/share/pasturestack/security/ubuntu-backports/." "$evidence/" +docker rm "$consumer" >/dev/null +consumer= +bundle=$(docker create "$bundle_image" /artifact-export-only) +docker cp "$bundle:/out/verify-consumer-evidence.py" "$scratch/verify-consumer-evidence.py" +docker cp "$bundle:/out/SHA256SUMS" "$scratch/bundle-SHA256SUMS" +docker rm "$bundle" >/dev/null +bundle= +python3 -B "$scratch/verify-consumer-evidence.py" \ + --evidence-dir "$evidence" --sbom "$sbom" \ + --expected-bundle-digest "$bundle_digest" \ + --bundle-checksums "$scratch/bundle-SHA256SUMS" diff --git a/.github/workflows/security-build.yml b/.github/workflows/security-build.yml index 316212b..f89d151 100644 --- a/.github/workflows/security-build.yml +++ b/.github/workflows/security-build.yml @@ -35,7 +35,7 @@ jobs: set -euo pipefail test "$(go env GOVERSION)" = go1.27.3 sudo --preserve-env=PATH,GOTOOLCHAIN,GOMAXPROCS,GOFLAGS bash scripts/validate.sh - docker build --build-arg VERSION=0.2.1 --build-arg REVISION="$GITHUB_SHA" -f package/Dockerfile -t local/secrets-flexvolume-plugin . + docker build --build-arg VERSION=0.2.2 --build-arg REVISION="$GITHUB_SHA" -f package/Dockerfile -t local/secrets-flexvolume-plugin . - name: Retain the exact verified runtime shell: bash run: | @@ -49,17 +49,25 @@ jobs: shell: bash run: | set -euo pipefail + mkdir -p "$RUNNER_TEMP/trivy-cache" scanner=aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969 PYTHONDONTWRITEBYTECODE=1 python3 .github/scripts/test_runtime_vulnerability_policy.py docker pull "$scanner" for runtime in local/secrets-flexvolume-plugin; do name=${runtime##*/}; name=${name%%:*} docker save "$runtime" --output "$RUNNER_TEMP/$name.tar" - docker run --rm -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --scanners vuln,secret --list-all-pkgs --format json --output "/evidence/$name-security.json" + docker run --rm -v "$RUNNER_TEMP/trivy-cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --scanners vuln,secret --list-all-pkgs --format json --output "/evidence/$name-security-raw.json" + docker run --rm -v "$RUNNER_TEMP/trivy-cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --format cyclonedx --output "/evidence/$name-sbom.cdx.json" + backports="$RUNNER_TEMP/secrets-flexvolume-plugin-ubuntu-backports" + bash .github/scripts/collect-ubuntu-backport-evidence.sh \ + "$runtime" "dist/security-runtime/$name-sbom.cdx.json" "$backports" \ + > "dist/security-runtime/$name-ubuntu-backports-verification.json" + tar -C "$backports" -czf "dist/security-runtime/$name-ubuntu-backports.tar.gz" . + docker run --rm -v "$backports:/backports:ro" -v "$RUNNER_TEMP/trivy-cache:/root/.cache/trivy" -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --vex /backports/openvex.json --skip-db-update --input /image.tar --scanners vuln,secret --list-all-pkgs --format json --output "/evidence/$name-security.json" python3 .github/scripts/enforce-runtime-vulnerabilities.py --repository PastureStack/secrets-flexvolume-plugin < "dist/security-runtime/$name-security.json" - docker run --rm -v "$RUNNER_TEMP/$name.tar:/image.tar:ro" -v "$PWD/dist/security-runtime:/evidence" "$scanner" image --input /image.tar --format cyclonedx --output "/evidence/$name-sbom.cdx.json" done - (cd dist/security-runtime && sha256sum -- *.json images.tar.gz source-revision.txt > SHA256SUMS) + (cd dist/security-runtime && sha256sum -- *.json *.tar.gz source-revision.txt > SHA256SUMS) + - name: Upload verified runtime and checksums if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -80,7 +88,7 @@ jobs: packages: write env: GH_TOKEN: ${{ github.token }} - RELEASE_TAG: v0.2.1 + RELEASE_TAG: v0.2.2 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: diff --git a/README.md b/README.md index f3155d1..c49032a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ PastureStack is an independent community effort to preserve, audit, and moderniz # Secret Volume Driver +Linux source candidate **`v0.2.2`** consumes verified Ubuntu security backports without adding runtime packages or changing the host's coreutils provider. Publication and integration checks must complete before deployment. + +The runtime recipe applies the qualified Ubuntu 26.04 backport bundle only to already-installed packages and preserves the selected coreutils provider. The immutable bundle digest and final-image checks are pending. Bundle manifests, qualification, exact-version OpenVEX, source inputs and install/verify receipts are retained under `/usr/share/pasturestack/security/ubuntu-backports/`; raw scan evidence and the existing full-severity release policy remain required. + `secrets-flexvolume-plugin` is the PastureStack Docker volume driver for delivering encrypted control-plane secrets to workloads. The driver exposes a Docker Volume Plugin API v1 socket, requests only the encrypted records authorized by an opaque volume token, authenticates every envelope, decrypts it with the host identity key, and materializes the result inside an isolated in-memory filesystem. The production entry point is: @@ -12,10 +16,10 @@ The production entry point is: secrets-flexvolume-plugin serve ``` -The release image starts that entry point automatically: +After publication, the candidate image starts that entry point automatically: ```text -ghcr.io/pasturestack/secrets-flexvolume-plugin:v0.2.1 +ghcr.io/pasturestack/secrets-flexvolume-plugin:v0.2.2 ``` Catalog deployment is the supported installation path. It runs one driver instance on each eligible host and supplies the compatible control-plane identity through the environment service. Operators do not pass plaintext secret values, private keys, or API credentials on the command line. @@ -85,5 +89,4 @@ finding with an official fix blocks release, regardless of severity. Unknown findings block unless a separately reviewed, exact not-affected statement is proved by the actual product dependency graph. LOW/MEDIUM findings without an official fix require the repository's exact CVE/package/version/PURL review ledger; -new or changed findings fail closed. This policy-only update does not replace any -already published immutable artifact. +new or changed findings fail closed. Each candidate must pass this policy against its exact image and package versions. diff --git a/package/Dockerfile b/package/Dockerfile index 5aebb9e..2b9a3c5 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -1,4 +1,6 @@ # syntax=docker/dockerfile:1.7 +ARG UBUNTU_SECURITY_BACKPORTS_IMAGE=ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a + FROM golang:1.27.3-bookworm@sha256:972b4110ba0f47539a975c31e52c64765e1ff19f2d74469ae4a595c6676e80a5 AS build ARG VERSION=dev @@ -11,7 +13,10 @@ RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \ -o /out/secrets-flexvolume-plugin \ ./cmd/secrets-flexvolume-plugin +FROM ${UBUNTU_SECURITY_BACKPORTS_IMAGE} AS ubuntu_security_backports + FROM ubuntu:26.04@sha256:2260313b31c8c011cd2eebe728008efac1b3982be73eb71348ea2648d2c0e09b +ARG UBUNTU_SECURITY_BACKPORTS_IMAGE ARG VERSION=dev ARG REVISION=unknown @@ -52,6 +57,19 @@ RUN set -eux; \ COPY --from=build /out/secrets-flexvolume-plugin /usr/local/bin/secrets-flexvolume-plugin +# Keep the build-only installer and package archives outside the final image. +RUN --mount=type=bind,from=ubuntu_security_backports,source=/out,target=/opt/pasturestack/ubuntu-security-backports,readonly \ + set -eux; \ + evidence=/usr/share/pasturestack/security/ubuntu-backports; \ + mkdir -p "$evidence"; \ + /opt/pasturestack/ubuntu-security-backports/install-existing-backports --install-in-docker-build > "$evidence/install.json"; \ + /opt/pasturestack/ubuntu-security-backports/install-existing-backports --verify-installed > "$evidence/verify.json"; \ + for file in manifest.json qualification.json source-inputs.lock.json openvex.json; do \ + cp "/opt/pasturestack/ubuntu-security-backports/$file" "$evidence/$file"; \ + done; \ + printf '%s\n' "$UBUNTU_SECURITY_BACKPORTS_IMAGE" > "$evidence/bundle-image.txt"; \ + (cd "$evidence" && sha256sum manifest.json qualification.json source-inputs.lock.json openvex.json install.json verify.json bundle-image.txt > SHA256SUMS) + USER 0:0 ENTRYPOINT ["/usr/local/bin/secrets-flexvolume-plugin"] CMD ["serve"] From e39c2ae441ee0221786694bdfc62df11ac4a971d Mon Sep 17 00:00:00 2001 From: chen21019 <19357113+chen21019@users.noreply.github.com> Date: Sun, 25 Oct 2026 06:55:31 +0800 Subject: [PATCH 2/2] Describe the current runtime without temporary release status --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c49032a..0cbd020 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ PastureStack is an independent community effort to preserve, audit, and moderniz # Secret Volume Driver -Linux source candidate **`v0.2.2`** consumes verified Ubuntu security backports without adding runtime packages or changing the host's coreutils provider. Publication and integration checks must complete before deployment. +Linux runtime **`v0.2.2`** consumes verified Ubuntu security backports without adding packages or changing the existing coreutils provider. The runtime recipe applies the qualified Ubuntu 26.04 backport bundle only to already-installed packages and preserves the selected coreutils provider. The immutable bundle digest and final-image checks are pending. Bundle manifests, qualification, exact-version OpenVEX, source inputs and install/verify receipts are retained under `/usr/share/pasturestack/security/ubuntu-backports/`; raw scan evidence and the existing full-severity release policy remain required.