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
56 changes: 43 additions & 13 deletions .github/workflows/publish-current-server.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ jobs:
python3 source/scripts/test-render-server-release-notes.py
python3 source/scripts/test-publisher-safety-guards.py
python3 source/scripts/test-web-console-sbom.py
python3 source/scripts/test-server-backport-consumer-contract.py

declared_release="$(sed -n 's/^ARG SERVER_RELEASE_TAG=//p' \
source/server/Dockerfile.web-compose-release | sort -u)"
Expand Down Expand Up @@ -556,6 +557,45 @@ jobs:
' "$evidence/server-nested-payloads.json" >>"$evidence/server-secrets.tsv"
test ! -s "$evidence/server-secrets.tsv"

docker run --rm \
-v "$RUNNER_TEMP/server-rootfs:/rootfs:ro" \
-v "$evidence:/evidence" \
-v "$RUNNER_TEMP/trivy-cache:/root/.cache/trivy" \
"$TRIVY_IMAGE" rootfs \
--format cyclonedx \
--output /evidence/server.cdx.json \
/rootfs
jq -e '
.bomFormat == "CycloneDX"
and ((.components | type) == "array")
and ((.components | length) > 0)
' "$evidence/server.cdx.json" >/dev/null

# Bind the candidate's retained metadata to the same immutable OCI
# before passing its exact-package VEX to native Trivy.
cp -a "$RUNNER_TEMP/server-rootfs/usr/share/pasturestack/security/ubuntu-backports" "$evidence/ubuntu-backports"
(cd "$evidence/ubuntu-backports" && sha256sum --check SHA256SUMS)
bundle_image="$(sed -n 's/^FROM \(ghcr.io\/pasturestack\/ubuntu-security-backports:v0\.1\.0@sha256:[0-9a-f]\{64\}\) AS ubuntu_security_backports$/\1/p' source/server/Dockerfile.web-compose-release)"
[[ "$bundle_image" =~ ^ghcr.io/pasturestack/ubuntu-security-backports:v0\.1\.0@sha256:[0-9a-f]{64}$ ]]
docker pull --platform linux/amd64 "$bundle_image"
mkdir -p "$evidence/bundle-tools"
bundle_container="$(docker create --entrypoint /unused "$bundle_image")"
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/server.cdx.json" \
--expected-bundle-digest "${bundle_image##*@}" \
--bundle-checksums "$evidence/bundle-tools/SHA256SUMS" \
>"$evidence/ubuntu-backports-validation.json"
tar -cf "$evidence/ubuntu-backports-evidence.tar" -C "$evidence" \
ubuntu-backports bundle-tools ubuntu-backports-validation.json

docker run --rm \
-v "$RUNNER_TEMP/server-rootfs:/rootfs:ro" \
-v "$evidence:/evidence" \
Expand All @@ -564,6 +604,7 @@ jobs:
--scanners vuln \
--skip-vex-repo-update \
--vex /evidence/server.openvex.json \
--vex /evidence/ubuntu-backports/openvex.json \
--format json \
--output /evidence/server-security-scan.json \
/rootfs
Expand All @@ -588,19 +629,6 @@ jobs:
"$evidence/server-vulnerabilities-unresolved.tsv" \
"$RELEASE_TAG" | tee "$evidence/vendor-pending-summary.txt"

docker run --rm \
-v "$RUNNER_TEMP/server-rootfs:/rootfs:ro" \
-v "$evidence:/evidence" \
-v "$RUNNER_TEMP/trivy-cache:/root/.cache/trivy" \
"$TRIVY_IMAGE" rootfs \
--format cyclonedx \
--output /evidence/server.cdx.json \
/rootfs
jq -e '
.bomFormat == "CycloneDX"
and ((.components | type) == "array")
and ((.components | length) > 0)
' "$evidence/server.cdx.json" >/dev/null
raw_count="$(wc -l <"$evidence/server-vulnerabilities-raw.tsv")"
vendor_pending_count="$(wc -l <"$evidence/server-vulnerabilities-unresolved.tsv" | tr -d ' ')"
browser_scan_coverage="$(jq -r '.coverage' "$evidence/web-console-runtime-scan-coverage.json")"
Expand Down Expand Up @@ -760,6 +788,7 @@ jobs:
security-summary.txt \
server.openvex.json \
server.vendor-pending.json \
ubuntu-backports-evidence.tar \
server-security-scan-raw.json \
server-security-scan.json \
server-nested-payloads.json \
Expand Down Expand Up @@ -800,6 +829,7 @@ jobs:
"$evidence/security-summary.txt" \
"$evidence/server.openvex.json" \
"$evidence/server.vendor-pending.json" \
"$evidence/ubuntu-backports-evidence.tar" \
"$evidence/server-security-scan-raw.json" \
"$evidence/server-security-scan.json" \
"$evidence/server-nested-payloads.json" \
Expand Down
29 changes: 29 additions & 0 deletions COMPATIBILITY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Compatibility Contract

<a id="server-v16552-runtime-backports"></a>

## Server v1.6.552 prepared, not published

This source candidate prepares the numeric `ghcr.io/pasturestack/server:v1.6.552`
image tag. It has not been published. The normal publisher must retain the exact
producer, OCI digest, SBOM, original vulnerability report and interpreted report
before the candidate can be used.

The digest-pinned, build-only Ubuntu backport bundle installs only existing
packages. It retains the original package set, selected coreutils provider and
configuration. The Python compiler keeps its original inputs; the final runtime
uses the qualified library packages. Source/native-test qualification and actual
installation receipts are retained under
`/usr/share/pasturestack/security/ubuntu-backports/`. These downstream Debian
packages apply accepted upstream fixes to pinned Ubuntu sources; they are not
packages issued by Canonical.

Node Agent `v1.2.33` pins base `v0.3.7`. Catalog `v0.3.17` records the component
producer commits, image digests, SBOMs and scan evidence. Existing environments
retain their configuration and require the normal infrastructure-stack upgrade
flow to adopt new Catalog revisions. No host firewall backend is selected or
changed by the runtime library installer.

Available fixes and unreviewed findings block publication. Officially unfixed
Low/Medium findings remain registered; exact-package code-absence decisions
require separate source, package and native-scanner evidence. The original raw
report is retained. See the [release note](docs/releases/server-1.6.552.md).

<a id="server-v16551-release-assets"></a>

## Server v1.6.551 published
Expand Down
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,24 @@ upstream history, authorship, licenses, and notices.

<a id="current-release"></a>

## Current release
## Current source candidate

Server [`v1.6.551`](https://github.com/PastureStack/server/releases/tag/v1.6.551) is published.
It retains the eight PCRE2 CVE fixes using the upstream-supported 10.46 backports and
original Ubuntu packaging. The two rebuilt runtime packages retain ABI, JIT,
POSIX interfaces and hardening. Its standalone Host API archive matches the
original producer; the incorrect 550 attachment is superseded.
Server `v1.6.552` is a prepared source candidate, not a published image.
It includes Ubuntu security backports from verified upstream releases and accepted
fixes. Each image updates only packages already installed, preserving its package
set, coreutils provider, configuration and library interfaces. The compiler stages
remain separate from the final runtime.

Web Console `1.6.195` and its original runtime SBOM, Engine `v0.183.354`,
Host API `0.38.8` and Temurin `25.0.5+8` retain their verified inputs.
The scoped 8080 upgrade and restart passed package/hash/linkage checks,
regex controls in grep, Git and MariaDB, and three active Host/Agent states.
Existing configuration, volumes, AppArmor and the previous rollback image remain.
Node Agent `v1.2.33` uses compatibility base `v0.3.7`; Catalog `v0.3.17`
references the corresponding verified component images.

See the [551 release note](docs/releases/server-1.6.551.md) and
[compatibility contract](COMPATIBILITY.md#server-v16551-release-assets)
for the immutable identity, verified assets and remaining risks.
The published release is [Server v1.6.551](https://github.com/PastureStack/server/releases/tag/v1.6.551),
with its [publication note](docs/releases/server-1.6.551.md).
See the [candidate note](docs/releases/server-1.6.552.md) and
[compatibility contract](COMPATIBILITY.md#server-v16552-runtime-backports)
for producer identities, immutable image digests, SBOMs and remaining findings.

Personal API Keys remain available without an accessible environment. See the [Host guide](docs/hosts/README.md) before enrolling a host.

Expand All @@ -54,22 +55,23 @@ Maintained CLI `0.6.20` propagates rejected requests as nonzero errors. Legacy `
## Quick start

Public GHCR downloads do not require a registry login. Keep all three named volumes.
The examples below use the published numeric `v1.6.551` tag.
The examples below use the numeric `v1.6.552` tag; run them only after its official release.
This candidate is not yet available from GHCR.

```sh
docker run -d --name pasturestack-server --restart unless-stopped -p 8080:8080 \
-v pasturestack-cattle:/var/lib/cattle \
-v pasturestack-mysql:/var/lib/mysql \
-v pasturestack-mysqllog:/var/log/mysql \
ghcr.io/pasturestack/server:v1.6.551
ghcr.io/pasturestack/server:v1.6.552
```

For HTTPS termination at a reverse proxy, set the exact public origin:

```yaml
services:
pasturestack-server:
image: ghcr.io/pasturestack/server:v1.6.551
image: ghcr.io/pasturestack/server:v1.6.552
restart: unless-stopped
ports:
- "8080:8080"
Expand Down
7 changes: 4 additions & 3 deletions docs/performance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ The following example is appropriate as a starting point for a dedicated
16-vCPU host with about 32 GiB of RAM. It is not a universal performance
profile; measure the real workload before increasing it further.

The example uses the published numeric Server v1.6.549 tag.
See the [release note](../releases/server-1.6.549.md) and the
The example prepares the numeric Server v1.6.552 tag; run it only after its official release and image have been published and read back.
This candidate is not yet available from GHCR.
See the [candidate note](../releases/server-1.6.552.md) and the
[current release](../../README.md#current-release) for component versions and
release details. Preserve the existing runtime overrides and all three named
volumes during an upgrade or restart.
Expand All @@ -20,7 +21,7 @@ evidence is not a performance benchmark; measure the actual workload.
```yaml
services:
pasturestack-server:
image: ghcr.io/pasturestack/server:v1.6.551
image: ghcr.io/pasturestack/server:v1.6.552
restart: unless-stopped
ports:
- "8080:8080"
Expand Down
38 changes: 38 additions & 0 deletions docs/releases/server-1.6.552.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Server v1.6.552 candidate

Prepared source only; no Server image or release has been published.

## Verified component inputs

This release consumes the qualified Ubuntu security backports in Server and its
component images. It updates only already-installed packages, preserves the
coreutils provider and configuration, and keeps compilers outside the final
runtime. The root Server image does not add jq, Rust coreutils or development
packages to obtain a clean scan.

The bundle binds the original upstream fixes, native package tests, actual GNU
and uutils installation fixtures, package archives and exact-package OpenVEX.
The published image has its own SBOM and installation verification. These are
separate from the bundle's data SBOM. Raw findings remain available alongside
the interpreted report. Unfixed findings and code-absence determinations are
reported separately from fixed vulnerabilities.

Web Console `1.6.195`, Engine `v0.183.354`, Host API `0.38.8` and Temurin
`25.0.5+8` retain their component inputs. Node Agent `v1.2.33` uses base
`v0.3.7`; Catalog `v0.3.17` records the corresponding component releases.

## Upgrade and rollback

Back up the database and all three named volumes before upgrading. Keep the
existing Compose environment variables, ports, restart policy, AppArmor,
public HTTPS origin and mounts. Use `ghcr.io/pasturestack/server:v1.6.552`;
do not keep old runtime bundle overrides mounted into the new image.

Upgrade existing infrastructure stacks through the normal Catalog workflow and
complete their upgrades after checking health. Preserve the previous image and
matching data backup for rollback. Do not run `docker compose down -v`.

The official release includes the producer commit, immutable image digest,
checksums, SBOMs, vulnerability reports and qualification receipts. Consult
[the compatibility contract](../../COMPATIBILITY.md#server-v16552-runtime-backports)
for the retained runtime boundaries.
24 changes: 12 additions & 12 deletions scripts/check-server-api-explorer-patch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ python3 scripts/test-web-console-sbom.py
python3 server/security/test_web_console_sbom_scan.py

require_marker "$release_dockerfile" \
'ARG SERVER_RELEASE_TAG=v1.6.551' \
'ARG SERVER_RELEASE_TAG=v1.6.552' \
SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING
require_marker "$release_dockerfile" \
'org.opencontainers.image.version="${SERVER_RELEASE_TAG}"' \
Expand Down Expand Up @@ -1138,10 +1138,10 @@ require_marker "$build_script" \
'--file server/Dockerfile.web-compose-release' \
SERVER_INCREMENTAL_RELEASE_BUILD_PATH_MISSING
require_marker "$build_script" \
'image=${IMAGE:-pasturestack-validation/server:v1.6.551}' \
'image=${IMAGE:-pasturestack-validation/server:v1.6.552}' \
SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING
require_marker "$build_script" \
'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.551}' \
'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.552}' \
SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING
require_marker "$build_script" \
'CATTLE_RANCHER_SERVER_VERSION="${server_release_tag}"' \
Expand Down Expand Up @@ -1597,13 +1597,13 @@ require_marker "$build_script" \
'grep -F "pasturestack-catalog-pinned-commit"' \
SERVER_CATALOG_PINNED_COMMIT_IMAGE_GATE_MISSING
require_marker "$release_dockerfile" \
'ENV PASTURESTACK_CATALOG_COMMIT=070e08d8f85ffc2779a0f97eb4e356c857812d34' \
'ENV PASTURESTACK_CATALOG_COMMIT=72b0d9767306baf7091fca021d0a2b6bdbca5d51' \
SERVER_CATALOG_VERSION_LABEL_COMMIT_MISSING
require_marker "$release_dockerfile" \
'"pinnedCommit":"070e08d8f85ffc2779a0f97eb4e356c857812d34"' \
'"pinnedCommit":"72b0d9767306baf7091fca021d0a2b6bdbca5d51"' \
SERVER_CATALOG_VERSION_LABEL_URL_MISSING
require_marker "$build_script" \
'PASTURESTACK_CATALOG_COMMIT=070e08d8f85ffc2779a0f97eb4e356c857812d34' \
'PASTURESTACK_CATALOG_COMMIT=72b0d9767306baf7091fca021d0a2b6bdbca5d51' \
SERVER_CATALOG_VERSION_LABEL_IMAGE_GATE_MISSING
for previous_release_marker in \
'# Server v1.6.462' \
Expand Down Expand Up @@ -1691,10 +1691,10 @@ fi
if grep -Fxq '## Current source candidate' README.md; then
for candidate_readme_marker in \
'<a id="current-release"></a>' \
'Server `v1.6.551` is a prepared source candidate, not a published image.' \
'Server `v1.6.552` is a prepared source candidate, not a published image.' \
'run them only after its official release' \
'This candidate is not yet available' \
'ghcr.io/pasturestack/server:v1.6.551'; do
'ghcr.io/pasturestack/server:v1.6.552'; do
require_marker README.md "$candidate_readme_marker" \
SERVER_CURRENT_CANDIDATE_README_MISSING
done
Expand Down Expand Up @@ -1980,7 +1980,7 @@ require_marker "$build_script" \
'PASTURESTACK_CURL_PACKAGE_VERSION=8.18.0-1ubuntu2.8' \
SERVER_CURL_IMAGE_VERSION_GATE_MISSING
require_marker "$build_script" \
'PASTURESTACK_GLIBC_PACKAGE_VERSION=2.43-2ubuntu2.4' \
'PASTURESTACK_GLIBC_PACKAGE_VERSION=2.43-2ubuntu2.4+pasturestack.1' \
SERVER_GLIBC_IMAGE_VERSION_GATE_MISSING
require_marker "$build_script" \
'PASTURESTACK_PERL_PACKAGE_VERSION=5.40.1-7ubuntu0.3' \
Expand Down Expand Up @@ -2300,7 +2300,7 @@ done
jq -e '
["CVE-2026-107928","CVE-2026-107929","CVE-2026-86409","CVE-2026-86410","CVE-2026-86412","CVE-2026-86414","CVE-2026-87862","CVE-2026-87863","CVE-2026-87864","CVE-2026-87865","CVE-2026-92386","CVE-2026-92387","CVE-2026-92388","CVE-2026-92389","CVE-2026-92390","CVE-2026-92391","CVE-2026-92392","CVE-2026-94266"] as $curl_fixed_cves
| .["@context"] == "https://openvex.dev/ns/v0.2.0"
and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.551"
and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.552"
and (.statements | length) == 56
and ([.statements[].vulnerability.name] | length == (unique | length))
and ([.statements[] | select(.status == "fixed") | .vulnerability.name] | sort)
Expand Down Expand Up @@ -2338,7 +2338,7 @@ jq -r '
| @tsv
' "$runtime_vendor_pending" | LC_ALL=C sort -u >"$vendor_pending_fixture"
bash "$vendor_pending_validator" "$runtime_vendor_pending" \
"$vendor_pending_fixture" v1.6.551 >/dev/null
"$vendor_pending_fixture" v1.6.552 >/dev/null
bash scripts/test-vendor-pending-findings.sh >/dev/null
rm -f "$vendor_pending_fixture"
trap - EXIT
Expand Down Expand Up @@ -2427,4 +2427,4 @@ for release_readback_contract in \
fi
done

printf 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.551 base=v1.6.460 engine=0.183.354 web_console=1.6.195 catalog_service=0.20.15 webhook_automation_service=0.10.5 authentication_service=0.4.46 curl=8.18.0-1ubuntu2.8 freemarker=2.3.35 artifact_scan=required vendor_pending=exact-set role_matrix=qa-required locale_layout=qa-required\n'
printf 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.552 base=v1.6.460 engine=0.183.354 web_console=1.6.195 catalog_service=0.20.15 webhook_automation_service=0.10.5 authentication_service=0.4.46 curl=8.18.0-1ubuntu2.8 freemarker=2.3.35 artifact_scan=required vendor_pending=exact-set role_matrix=qa-required locale_layout=qa-required\n'
2 changes: 1 addition & 1 deletion scripts/check-server-runtime-image-references.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cd "$repo_root"

approved_registry=ghcr.io/pasturestack
approved_agent="${approved_registry}/node-agent:v1.2.31"
current_agent="${approved_registry}/node-agent:v1.2.32"
current_agent="${approved_registry}/node-agent:v1.2.33"
approved_balancer="${approved_registry}/load-balancer-service:v0.9.33"
# Historical recipes and opt-in migration tools keep their reviewed coordinates.
historical_balancer="${approved_registry}/load-balancer-service:v0.9.27"
Expand Down
Loading