diff --git a/.github/workflows/runtime-security.yml b/.github/workflows/runtime-security.yml index 4358cf1..348ae1f 100644 --- a/.github/workflows/runtime-security.yml +++ b/.github/workflows/runtime-security.yml @@ -48,6 +48,7 @@ jobs: set -euo pipefail test "$GITHUB_REF" = refs/heads/main [[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] + test "$RELEASE_TAG" = 'v0.3.3' test -z "$(git status --porcelain)" test "$(git rev-parse HEAD)" = "$GITHUB_SHA" test "$(gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/main" --jq .object.sha)" = "$GITHUB_SHA" @@ -73,6 +74,8 @@ jobs: trap 'docker rm "$container" >/dev/null' EXIT docker cp "$container:/usr/local/bin/network-policy-manager" evidence/product docker cp "$container:/usr/share/pasturestack/ubuntu-security-packages.tsv" evidence/ubuntu-security-packages.tsv + docker cp "$container:/usr/share/pasturestack/security/ubuntu-backports" evidence/ubuntu-backports + (cd evidence/ubuntu-backports && sha256sum --check SHA256SUMS) docker cp "$container:/etc/ssl/certs/ca-certificates.crt" evidence/ca-certificates.crt go version -m evidence/product | tee evidence/product-go-version.txt grep -F 'go1.27.3' evidence/product-go-version.txt @@ -88,15 +91,46 @@ jobs: TESTED_IMAGE: local/network-policy-manager:${{ inputs.release_tag || 'dev' }} run: | set -euo pipefail - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD/evidence:/evidence" \ - "$TRIVY_IMAGE" image --scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \ + cache="$RUNNER_TEMP/ubuntu-backports-trivy-cache" + mkdir -p "$cache" + docker run --rm -v "$cache:/root/.cache/trivy" "$TRIVY_IMAGE" image --download-db-only + # Retain the untouched all-severity raw report and the actual image SBOM. + docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$cache:/root/.cache/trivy" -v "$PWD/evidence:/evidence" "$TRIVY_IMAGE" \ + image --skip-db-update --scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \ --exit-code 0 --format json --output /evidence/image-security.json "$TESTED_IMAGE" - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v "$PWD/evidence:/evidence" \ - "$TRIVY_IMAGE" image --format cyclonedx --output /evidence/image.cdx.json "$TESTED_IMAGE" + docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$cache:/root/.cache/trivy" -v "$PWD/evidence:/evidence" "$TRIVY_IMAGE" \ + image --skip-db-update --format cyclonedx --output /evidence/image.cdx.json "$TESTED_IMAGE" + bundle_image='ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' + mkdir -p evidence/bundle-tools + bundle_container=$(docker create "$bundle_image" unused) + trap 'docker rm "$bundle_container" >/dev/null' EXIT + docker cp "$bundle_container:/out/verify-consumer-evidence.py" evidence/bundle-tools/verify-consumer-evidence.py + docker cp "$bundle_container:/out/SHA256SUMS" evidence/bundle-tools/SHA256SUMS + docker rm "$bundle_container" >/dev/null + trap - EXIT + (cd evidence/bundle-tools && \ + test "$(grep -Ec '^[0-9a-f]{64} verify-consumer-evidence\.py$' SHA256SUMS)" -eq 1 && \ + grep -E '^[0-9a-f]{64} verify-consumer-evidence\.py$' SHA256SUMS | sha256sum --check -) + python3 evidence/bundle-tools/verify-consumer-evidence.py \ + --evidence-dir evidence/ubuntu-backports --sbom evidence/image.cdx.json \ + --bundle-checksums evidence/bundle-tools/SHA256SUMS \ + --expected-bundle-digest 'sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > evidence/ubuntu-backports-validation.json + # Only native Trivy interprets the exact qualified OpenVEX statements. + docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \ + -v "$cache:/root/.cache/trivy" -v "$PWD/evidence:/evidence" "$TRIVY_IMAGE" \ + image --skip-db-update --scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \ + --vex /evidence/ubuntu-backports/openvex.json --exit-code 0 --format json \ + --output /evidence/image-security.effective.json "$TESTED_IMAGE" PYTHONDONTWRITEBYTECODE=1 python3 .github/scripts/test_runtime_vulnerability_policy.py python3 .github/scripts/enforce-runtime-vulnerabilities.py \ - evidence/image-security.json .github/runtime-unfixed.json \ + evidence/image-security.effective.json .github/runtime-unfixed.json \ --repository "$GITHUB_REPOSITORY" + tar -cf evidence/ubuntu-backports-evidence.tar -C evidence ubuntu-backports + sha256sum evidence/image-security.json evidence/image-security.effective.json \ + evidence/image.cdx.json evidence/ubuntu-backports-validation.json \ + evidence/ubuntu-backports-evidence.tar >> evidence/SHA256SUMS - name: Publish the tested image once id: publish @@ -148,7 +182,7 @@ jobs: -f ref="refs/tags/$RELEASE_TAG" -f sha="$tag_sha" >/dev/null gh release create "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" --verify-tag \ --title "$RELEASE_TAG" --notes-file evidence/published.txt \ - evidence/published.txt evidence/published.sha256 evidence/*.json + evidence/published.txt evidence/published.sha256 evidence/*.json evidence/ubuntu-backports-evidence.tar - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: always() diff --git a/README.md b/README.md index e7a5fbd..d0d5d5a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Network Policy Manager -Current source builds use Go 1.27.3 while the Go language minimum remains 1.26.0. Ubuntu 26.04 images install the checksum-pinned `ca-certificates` 20260816ubuntu0.26.04.1 package with only officially fixed, already-installed packages advanced by the reviewed security overlay. These source inputs take effect in newly built artifacts; existing published release coordinates below describe their original artifacts. +Linux runtime **`v0.3.3`** integrates shared Ubuntu 26.04 security backports for already-installed packages while preserving the selected coreutils provider. + +The image retains bundle manifests, source inputs and installation receipts under `/usr/share/pasturestack/security/ubuntu-backports/`. This repository provides a network-policy compiler and a host enforcement agent for PastureStack. The agent reads the local metadata endpoint, validates a bounded topology and policy snapshot, and installs one exact, independently owned nftables table on each host. @@ -10,9 +12,8 @@ PastureStack is an independent community effort to preserve, audit, and moderniz ## Status -The current public release is [v0.3.2](https://github.com/PastureStack/network-policy-manager/releases/tag/v0.3.2), -and the Catalog image is `ghcr.io/pasturestack/network-policy-manager:v0.3.2`. -Catalog template revisions are versioned independently from image tags. +Select `ghcr.io/pasturestack/network-policy-manager:v0.3.3` through the Catalog. +Catalog template revisions remain independently versioned. The default command remains a non-mutating audit compiler. `serve` is the enforcement mode used by the Catalog package. It supports live metadata reconciliation, deterministic rule compilation, an atomic nftables transaction, health status without identifiers, bounded stale-data handling, and exact cleanup. diff --git a/package/Dockerfile b/package/Dockerfile index f19d656..5657085 100644 --- a/package/Dockerfile +++ b/package/Dockerfile @@ -1,4 +1,5 @@ # syntax=docker/dockerfile:1.7 +FROM ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a AS ubuntu_security_backports FROM golang:1.27.3-bookworm@sha256:972b4110ba0f47539a975c31e52c64765e1ff19f2d74469ae4a595c6676e80a5 AS build ARG VERSION=dev @@ -52,6 +53,22 @@ RUN set -eux; \ COPY --from=build /out/network-policy-manager /usr/local/bin/network-policy-manager +# Install only qualified packages already present after the final Ubuntu update. +# This read-only build mount leaves no installer, archive or extra runtime tool. +RUN --mount=from=ubuntu_security_backports,source=/out,target=/opt/pasturestack/ubuntu-security-backports,ro \ + 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 document in manifest.json qualification.json openvex.json source-inputs.lock.json; do \ + cp "/opt/pasturestack/ubuntu-security-backports/${document}" "${evidence}/${document}"; \ + done; \ + printf '%s\n' 'ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > "${evidence}/bundle-image.txt"; \ + (cd "${evidence}" && sha256sum manifest.json qualification.json openvex.json source-inputs.lock.json install.json verify.json bundle-image.txt > SHA256SUMS); \ + dpkg-query -W -f='${binary:Package}\t${Version}\n' | LC_ALL=C sort > /usr/share/pasturestack/ubuntu-security-packages.tsv; \ + rm -f /var/cache/ldconfig/aux-cache + USER 0:0 ENTRYPOINT ["/usr/local/bin/network-policy-manager"] CMD ["serve"]