Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
41 changes: 38 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,47 @@ jobs:
--scanners vuln,secret --severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL \
--format json \
--output "/release/resource-scheduler-${RELEASE_TAG#v}-security.json" "$RUNTIME_IMAGE"
bash scripts/assess-runtime-vulnerabilities \
"$release_dir/resource-scheduler-${RELEASE_TAG#v}-security.json" \
"$release_dir" "$RUNTIME_IMAGE"
docker run --rm --network none \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD/$release_dir:/release" \
-v "$cache:/root/.cache/trivy" \
"$TRIVY_IMAGE" image --skip-db-update --offline-scan --format cyclonedx \
--output "/release/resource-scheduler-${RELEASE_TAG#v}-image.cdx.json" "$RUNTIME_IMAGE"
mkdir -p "$release_dir"
consumer_container=$(docker create "$RUNTIME_IMAGE" /bin/true)
if docker cp "$consumer_container:/usr/share/pasturestack/security/ubuntu-backports" "$release_dir"/ubuntu-backports; then
docker rm "$consumer_container" >/dev/null
else
docker rm "$consumer_container" >/dev/null
exit 1
fi
(cd "$release_dir"/ubuntu-backports && sha256sum --check SHA256SUMS)
bundle_image='ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a'
mkdir -p "$release_dir"/bundle-tools
bundle_container=$(docker create "$bundle_image" unused)
if docker cp "$bundle_container:/out/verify-consumer-evidence.py" "$release_dir"/bundle-tools/verify-consumer-evidence.py && \
docker cp "$bundle_container:/out/SHA256SUMS" "$release_dir"/bundle-tools/SHA256SUMS; then
docker rm "$bundle_container" >/dev/null
else
docker rm "$bundle_container" >/dev/null
exit 1
fi
(cd "$release_dir"/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 "$release_dir"/bundle-tools/verify-consumer-evidence.py \
--evidence-dir "$release_dir"/ubuntu-backports --sbom "$release_dir/resource-scheduler-${RELEASE_TAG#v}-image.cdx.json" \
--bundle-checksums "$release_dir"/bundle-tools/SHA256SUMS \
--expected-bundle-digest 'sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > "$release_dir"/ubuntu-backports-validation.json
docker run --rm --network none -v /var/run/docker.sock:/var/run/docker.sock \
-v "$PWD/$release_dir:/release" -v "$cache:/root/.cache/trivy" "$TRIVY_IMAGE" \
image --skip-db-update --offline-scan --scanners vuln,secret \
--severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --vex /release/ubuntu-backports/openvex.json \
--format json --output "/release/resource-scheduler-${RELEASE_TAG#v}-security.effective.json" "$RUNTIME_IMAGE"
bash scripts/assess-runtime-vulnerabilities \
"$release_dir/resource-scheduler-${RELEASE_TAG#v}-security.effective.json" \
"$release_dir" "$RUNTIME_IMAGE"
tar -cf "$release_dir/ubuntu-backports-evidence.tar" -C "$release_dir" ubuntu-backports ubuntu-backports-validation.json
docker run --rm --entrypoint cat "$RUNTIME_IMAGE" \
/usr/share/pasturestack/manifests/runtime-ubuntu-packages.tsv \
> "$release_dir/resource-scheduler-${RELEASE_TAG#v}-ubuntu-packages.tsv"
Expand All @@ -113,6 +145,7 @@ jobs:
"resource-scheduler-${RELEASE_TAG#v}-linux-amd64.tar.xz" \
"resource-scheduler-${RELEASE_TAG#v}-image.cdx.json" \
"resource-scheduler-${RELEASE_TAG#v}-security.json" \
"resource-scheduler-${RELEASE_TAG#v}-security.effective.json" ubuntu-backports-evidence.tar \
"resource-scheduler-${RELEASE_TAG#v}-ubuntu-packages.tsv" \
runtime-risk-summary.txt \
runtime-vendor-unfixed.tsv \
Expand Down Expand Up @@ -158,6 +191,8 @@ jobs:
"dist/release/resource-scheduler-${RELEASE_TAG#v}-linux-amd64.tar.xz" \
"dist/release/resource-scheduler-${RELEASE_TAG#v}-image.cdx.json" \
"dist/release/resource-scheduler-${RELEASE_TAG#v}-security.json" \
"dist/release/resource-scheduler-${RELEASE_TAG#v}-security.effective.json" \
dist/release/ubuntu-backports-evidence.tar \
"dist/release/resource-scheduler-${RELEASE_TAG#v}-ubuntu-packages.tsv" \
dist/release/runtime-risk-summary.txt \
dist/release/runtime-vendor-unfixed.tsv \
Expand Down
57 changes: 49 additions & 8 deletions .github/workflows/supply-chain.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 90
env:
CANDIDATE_VERSION: v0.8.20
CANDIDATE_VERSION: v0.8.21
DAPPER_IMAGE: local/resource-scheduler-dapper:${{ github.sha }}
TRIVY_IMAGE: aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969

Expand Down Expand Up @@ -272,18 +272,58 @@ jobs:
--output "/evidence/${scope}.cdx.json" "$image"
done

- name: Validate qualified backports and apply native runtime OpenVEX
shell: bash
run: |
set -euo pipefail
mkdir -p evidence
consumer_container=$(docker create "$RUNTIME_IMAGE" /bin/true)
if docker cp "$consumer_container:/usr/share/pasturestack/security/ubuntu-backports" evidence/ubuntu-backports; then
docker rm "$consumer_container" >/dev/null
else
docker rm "$consumer_container" >/dev/null
exit 1
fi
(cd evidence/ubuntu-backports && sha256sum --check SHA256SUMS)
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)
if 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; then
docker rm "$bundle_container" >/dev/null
else
docker rm "$bundle_container" >/dev/null
exit 1
fi
(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/runtime.cdx.json \
--bundle-checksums evidence/bundle-tools/SHA256SUMS \
--expected-bundle-digest 'sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a' > evidence/ubuntu-backports-validation.json
trivy_cache="$RUNNER_TEMP/resource-scheduler-trivy-cache"
docker run --rm --network none --volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$PWD/evidence:/evidence" --volume "$trivy_cache:/root/.cache/trivy" \
"$TRIVY_IMAGE" image --skip-db-update --offline-scan --scanners vuln,secret \
--severity UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL --vex /evidence/ubuntu-backports/openvex.json \
--format json --output /evidence/runtime-security.effective.json "$RUNTIME_IMAGE"

- name: Enforce runtime and builder security boundaries
shell: bash
run: |
set -euo pipefail
: > evidence/security-summary.txt
jq '{critical: [.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL")] | length,
high: [.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH")] | length}' \
evidence/runtime-security.json > evidence/runtime-raw-severity-counts.json
source_secrets="$(jq '[.Results[]?.Secrets[]?] | length' evidence/source-security.json)"
runtime_secrets="$(jq '[.Results[]?.Secrets[]?] | length' evidence/runtime-security.json)"
runtime_critical="$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL")] | length' evidence/runtime-security.json)"
runtime_high="$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH")] | length' evidence/runtime-security.json)"
runtime_vulnerabilities="$(jq '[.Results[]?.Vulnerabilities[]?] | length' evidence/runtime-security.json)"
runtime_secrets="$(jq '[.Results[]?.Secrets[]?] | length' evidence/runtime-security.effective.json)"
runtime_critical="$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL")] | length' evidence/runtime-security.effective.json)"
runtime_high="$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH")] | length' evidence/runtime-security.effective.json)"
runtime_vulnerabilities="$(jq '[.Results[]?.Vulnerabilities[]?] | length' evidence/runtime-security.effective.json)"
bash scripts/assess-runtime-vulnerabilities \
evidence/runtime-security.json evidence "$RUNTIME_IMAGE"
evidence/runtime-security.effective.json evidence "$RUNTIME_IMAGE"
runtime_vendor_unfixed="$(sed -n 's/^runtime_vendor_unfixed_low_medium=//p' evidence/runtime-risk-summary.txt)"
runtime_actionable="$(sed -n 's/^runtime_actionable=//p' evidence/runtime-risk-summary.txt)"
dapper_secrets="$(jq '[.Results[]?.Secrets[]?] | length' evidence/dapper-security.json)"
Expand Down Expand Up @@ -329,9 +369,10 @@ jobs:
mkdir -p dist/security-runtime
docker image inspect "$RUNTIME_IMAGE" > dist/security-runtime/images.json
docker save "$RUNTIME_IMAGE" | gzip -n > dist/security-runtime/images.tar.gz
cp evidence/runtime-security.json evidence/runtime.cdx.json dist/security-runtime/
cp evidence/runtime-security.json evidence/runtime-security.effective.json evidence/runtime.cdx.json dist/security-runtime/
tar -cf dist/security-runtime/ubuntu-backports-evidence.tar -C evidence ubuntu-backports ubuntu-backports-validation.json
printf '%s\n' "$GITHUB_SHA" > dist/security-runtime/source-revision.txt
(cd dist/security-runtime && sha256sum -- *.json images.tar.gz source-revision.txt > SHA256SUMS)
(cd dist/security-runtime && sha256sum -- *.json *.tar images.tar.gz source-revision.txt > SHA256SUMS)
- name: Retain verified runtime for immutable publication
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand Down
40 changes: 8 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
# PastureStack Resource Scheduler

The current published release is [v0.8.20](https://github.com/PastureStack/resource-scheduler/releases/tag/v0.8.20),
produced from `35d3a67c62df4b22d7167da3d73dd9dbc4905e66` by the existing
[release workflow](https://github.com/PastureStack/resource-scheduler/actions/runs/39961862641).
Its runtime digest is `sha256:e5a389273344585fca5c4513060e5289b30ca13046d8ec286b8563952f1325d4`.
Only `release.yml` publishes; `supply-chain.yml` retains verification evidence
without a second publisher. Later source changes do not replace released bytes.
Linux runtime **`v0.8.21`** 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/`.

Resource Scheduler is the control-plane daemon that tracks host capacity, labels, and host-port reservations. It consumes the dated metadata API, handles scheduling events, ranks eligible hosts, reserves and releases resources, and exposes the health endpoint used by the infrastructure catalog.

PastureStack is an independent community effort to preserve, audit, and modernize the Rancher 1.6 ecosystem. It is not affiliated with or endorsed by Rancher Labs or SUSE.

**Upstream:** [`rancher/scheduler`](https://github.com/rancher/scheduler). This GitHub fork retains the upstream Git history, authorship, dates, and license notices. PastureStack maintenance is consolidated into one commit after the preserved upstream boundary.

The current published release is [`v0.8.20`](https://github.com/PastureStack/resource-scheduler/releases/tag/v0.8.20).
The corresponding Catalog version `5` is recorded in the
[Catalog update](https://github.com/PastureStack/catalog-templates/pull/18).

Release `v0.8.20` refreshes the official Go security release and Ubuntu packages.
Its actual runtime scan has 0 High/Critical findings, 0 vendor-fixed findings,
and 0 secrets. The 4 Low and 47 Medium vendor-unfixed findings remain
`under_investigation` in the release risk register and OpenVEX; they are not
resolved. Release checksums and the SBOM and image build-provenance attestations
were verified against the exact signed tag, source commit, and release workflow.
Publication does not establish a managed-system upgrade or rollback result.

Its disposable builder also selects the official `golang.org/x/net` 0.60.0,
The disposable builder also selects the official `golang.org/x/net` 0.60.0,
OpenTelemetry-Go 1.45.0, and containerd 2.3.6 security updates for Docker CLI
and Buildx. These tools are not copied into the runtime image.

Expand All @@ -37,20 +22,12 @@ vendor-fixed builder finding remain blocking. This does not assess the host
kernel; vendor-unfixed Low/Medium and unrated builder findings retain their
original severity and `under_investigation` status.

The [native evidence run](https://github.com/PastureStack/resource-scheduler/actions/runs/39357570483)
retains the raw builder scan: 8 Critical and 192 High header source-package
matches are separately classified by 200 exact `not_affected` statements.
Another 2,600 vendor-unfixed package findings remain recorded, including the
unrated `GO-2026-5932` module advisory. The actual Buildx compilation graph
contains no `golang.org/x/crypto/openpgp` packages; that fact does not remove
the module finding or assess any host kernel.

## Runtime image

The maintained image is published from this repository as:
The Linux image coordinate is:

```text
ghcr.io/pasturestack/resource-scheduler:<version>
ghcr.io/pasturestack/resource-scheduler:v0.8.21
```

This image is a system component, not a standalone application. The PastureStack infrastructure catalog supplies the control-plane URL, scoped access credentials, metadata endpoint, health-check configuration, and an explicit numeric version tag. The container runs as UID/GID `10001:10001`; only the scheduler binary receives `cap_net_bind_service` so the established port `80` health contract can remain available without a root process.
Expand All @@ -71,7 +48,7 @@ make validate
bash scripts/check-build-downloads
go list -mod=vendor ./...
bash scripts/check-migration-policy
VERSION_OVERRIDE=v0.8.20 IMAGE_NAMESPACE=pasturestack make package
VERSION_OVERRIDE=v0.8.21 IMAGE_NAMESPACE=pasturestack make package
```

CI validates source and dependency locks, tests and reproducible builds, and generates short-lived security evidence. Releases are published only from an annotated, pure numeric SemVer tag that resolves to the reviewed commit.
Expand Down Expand Up @@ -101,5 +78,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 release must pass this policy against its exact image and package versions.
24 changes: 24 additions & 0 deletions package/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# syntax=docker/dockerfile:1.7
ARG SOURCE_DATE_EPOCH
ARG UBUNTU_IMAGE=ubuntu:26.04@sha256:2260313b31c8c011cd2eebe728008efac1b3982be73eb71348ea2648d2c0e09b
FROM ghcr.io/pasturestack/ubuntu-security-backports:v0.1.0@sha256:2742a3d429e4e14bc587f6dedc51ded4246cf90bbaedcd86c67d0885e32a6f2a AS ubuntu_security_backports
FROM ${UBUNTU_IMAGE} AS snapshot-ca-bootstrap
ADD --checksum=sha256:5b6326f1932cfd7be57130561dc78192f09ed9f58bfbe6606ed0c50510c3b6cd \
https://archive.ubuntu.com/ubuntu/pool/main/c/ca-certificates/ca-certificates_20260816ubuntu0.26.04.1_all.deb \
Expand Down Expand Up @@ -79,6 +81,28 @@ RUN set -eux; \
rm -f /var/log/lastlog /var/log/faillog

ENV HOME=/home/pasturestack
# Install qualified backports only for packages already in this runtime.
# The immutable read-only build mount adds no installer or interpreter to it.
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; \
{ \
printf 'record\tname\tarchitecture\tversion\n'; \
printf 'metadata\tschema\t-\tpasturestack.dpkg-manifest/v1\n'; \
printf 'metadata\tubuntu_snapshot\t-\t%s\n' "${UBUNTU_SNAPSHOT}"; \
dpkg-query -W -f='package\t${binary:Package}\t${Architecture}\t${Version}\n' | LC_ALL=C sort; \
} > /usr/share/pasturestack/manifests/runtime-ubuntu-packages.tsv; \
rm -f /var/cache/ldconfig/aux-cache

USER 10001:10001

LABEL org.opencontainers.image.title="PastureStack Resource Scheduler" \
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-migration-policy
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ done
grep -Fq "PastureStack is an independent community effort to preserve, audit, and modernize the ${legacy_title} 1.6 ecosystem. It is not affiliated with or endorsed by ${legacy_title} Labs or SUSE." README.md || fail "independence_notice_missing"
grep -Fq 'ad28c1d94b7f1b1814fa6404886398b4f4094d64' ORIGIN.md || fail "upstream_boundary_missing"
grep -Fq 'ghcr.io/pasturestack/resource-scheduler' README.md || fail "public_image_missing"
grep -Fq 'v0.8.20' README.md || fail "current_numeric_release_missing"
grep -Fq 'v0.8.21' README.md || fail "current_numeric_release_missing"
grep -Fq "[[ \"\$RELEASE_TAG\" =~ ^v[0-9]+\\.[0-9]+\\.[0-9]+\$ ]]" .github/workflows/release.yml || fail "numeric_release_gate_missing"

if git grep -I -n -E "${legacy_brand}-1\\.6-|${retired_short}" -- ':!vendor/**' ':!LICENSES/**' >/tmp/resource-scheduler-policy-matches 2>/dev/null; then
Expand Down
Loading