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: 41 additions & 0 deletions docs/releases/server-1.6.535.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Server v1.6.535

This patch packages immutable Engine `v0.183.349` with unchanged Web Console
`1.6.189` and the existing component set.

## Scoped API Key action repair

Fifteen exact persisted-resource/action pairs are registered centrally, including
Stack outputs and Service continue-upgrade. Queued custom-Key work rechecks the
same resource type and original operation. Owner authority, ancestry, explicit
deny, revision and expiration checks remain in place. Full and legacy Keys keep
the normal authorization path; unsupported multi-target and security/delegation
operations remain fail-closed. No authorization implementation is copied into
plugins.

Engine producer: `0733430fac11892a17ba53749fe02d99d26b1f52`.
`cattle.jar` SHA-256:
`6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04`.
The normal required checks, signed merge, original release packager, tested-class
byte comparison and anonymous immutable component readback passed. The focused
Engine suite passed 150 cases without replaying unrelated suites.

## Acceptance boundaries

The previous Server's normal-vs-Full/legacy read comparison and six-role OIDC
normal-vs-Full checks are carried as their original evidence. They cover the
tested accounts and operations, not every account, action or matrix row. Native
packaged action acceptance, official final-image security checks, deployment and
rollback are separate gates; component publication alone does not prove them.

## Upgrade and rollback

There is no database migration. Preserve the existing Compose environment,
volumes, restart policy, AppArmor, public HTTPS origin, OIDC/MFA, performance
settings and actual firewall backend. Retain the last working image. Roll back
code without restoring old Key policy, revocation, expiry or database state.

The existing Ubuntu curl backport and precise OpenVEX decisions are unchanged.
Unfixed LOW/MEDIUM findings remain in the versioned vendor-pending tracker;
none is hidden or promoted to a HIGH waiver. The normal source, CodeQL and
final-image security gates remain required.
26 changes: 13 additions & 13 deletions scripts/check-server-api-explorer-patch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ require_marker "$release_dockerfile" \
'ARG BASE_IMAGE=ghcr.io/pasturestack/server:v1.6.460@sha256:c855af8aea232dacc5bb6df68e2271d482c68b53c43ab0c108ec19118f5ab403' \
SERVER_INCREMENTAL_RELEASE_BASE_MISSING
require_marker "$release_dockerfile" \
'ARG SERVER_RELEASE_TAG=v1.6.534' \
'ARG SERVER_RELEASE_TAG=v1.6.535' \
SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING
require_marker "$release_dockerfile" \
'org.opencontainers.image.version="${SERVER_RELEASE_TAG}"' \
Expand Down Expand Up @@ -1059,21 +1059,21 @@ 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.534}' \
'image=${IMAGE:-pasturestack-validation/server:v1.6.535}' \
SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING
require_marker "$build_script" \
'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.534}' \
'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.535}' \
SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING
require_marker "$build_script" \
'CATTLE_RANCHER_SERVER_VERSION="${server_release_tag}"' \
SERVER_INCREMENTAL_RELEASE_BUILD_RUNTIME_VERSION_MISSING
for release_engine_marker in \
'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.348' \
'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349' \
'ARG ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar' \
'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=72581f6eead8633b6bbafbe15512cd44561b9ff25df68d00dd7120ad507aa449' \
'ARG ORCHESTRATION_ENGINE_COMMIT=f19cd64183c0fa93464e9a9f9c2477c9e902b56d' \
'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04' \
'ARG ORCHESTRATION_ENGINE_COMMIT=0733430fac11892a17ba53749fe02d99d26b1f52' \
'COPY --from=release_artifacts /out/orchestration-engine.jar /tmp/orchestration-engine.jar' \
'ARG ORCHESTRATION_ENGINE_VERSION=0.183.348' \
'ARG ORCHESTRATION_ENGINE_VERSION=0.183.349' \
'grep -Fx "Implementation-Version: ${ORCHESTRATION_ENGINE_VERSION}"' \
'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar' \
'cattle-app-config-${ORCHESTRATION_ENGINE_VERSION}.jar' \
Expand All @@ -1094,10 +1094,10 @@ for release_engine_marker in \
SERVER_INCREMENTAL_ENGINE_REPLACEMENT_MISSING
done
for release_engine_build_marker in \
'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.348}' \
'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349}' \
'orchestration_engine_artifact=${ORCHESTRATION_ENGINE_ARTIFACT:-cattle.jar}' \
'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-72581f6eead8633b6bbafbe15512cd44561b9ff25df68d00dd7120ad507aa449}' \
'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-f19cd64183c0fa93464e9a9f9c2477c9e902b56d}' \
'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04}' \
'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-0733430fac11892a17ba53749fe02d99d26b1f52}' \
'CATTLE_CATTLE_VERSION="${orchestration_engine_release_tag}"' \
'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar' \
'test "${hazelcast_entry}" = "WEB-INF/lib/hazelcast-5.7.5.jar"'; do
Expand Down Expand Up @@ -2158,7 +2158,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.534"
and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.535"
and (.statements | length) == 69
and ([.statements[].vulnerability.name] | length == (unique | length))
and ([.statements[] | select(.status == "fixed") | .vulnerability.name] | sort)
Expand Down Expand Up @@ -2196,7 +2196,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.534 >/dev/null
"$vendor_pending_fixture" v1.6.535 >/dev/null
bash scripts/test-vendor-pending-findings.sh >/dev/null
rm -f "$vendor_pending_fixture"
trap - EXIT
Expand Down Expand Up @@ -2285,4 +2285,4 @@ for release_readback_contract in \
fi
done

printf 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.534 base=v1.6.460 engine=0.183.348 web_console=1.6.189 catalog_service=0.20.13 webhook_automation_service=0.10.4 authentication_service=0.4.43 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.535 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 webhook_automation_service=0.10.4 authentication_service=0.4.43 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'
54 changes: 27 additions & 27 deletions scripts/test-current-server-packaging-contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@
WEB_SHA = '1c90e273b7db8ebf9d851a0ae1ec49dc59067b5ee1099ea3886919c1a79ccdfc'
WEB_SOURCE = 'f30f5e81dd9ee25878c3aff681eed5bb61883453'
CATALOG_COMMIT = 'b6b658888fce50d3ec217eb4eba0f26ab0113baf'
ENGINE_SHA = '72581f6eead8633b6bbafbe15512cd44561b9ff25df68d00dd7120ad507aa449'
ENGINE_SOURCE = 'f19cd64183c0fa93464e9a9f9c2477c9e902b56d'
ENGINE_SHA = '6e61f05598c12941c3b07ebfcf81f40e7fb1bd5439ec4c7d9c34484306378f04'
ENGINE_SOURCE = '0733430fac11892a17ba53749fe02d99d26b1f52'
OLD_COORDINATES = {
'v1.6.534': 'v1.6.521',
'v1.6.535': 'v1.6.521',
'1.6.189': '1.6.181',
WEB_SHA: '9199681f2c4311f3fbe8727fcf0f6fa136c9bafe9fbe9d13878c55df442a7a03',
WEB_SOURCE: '7f2bdad0c90a3241693c2ddd4475202ababba550',
CATALOG_COMMIT: '7670ffd81d5f0b5570197fb03c7e55b46da45bf3',
}
# Engine348 and Web189 use the reviewed component input identities.
# Engine349 and Web189 use the reviewed component input identities.
# Published521 component values remain mutation controls.
# Component coordinates do not establish Server534 artifact/runtime PASS.
# Component coordinates do not establish Server535 artifact/runtime PASS.
CATALOG_FIELDS = (
('VERSION', 'version', '0.20.13'),
('COMMIT', 'commit', '4c39c73a8131ba06e9ff0aaec3b95cc27e049324'),
Expand All @@ -41,13 +41,13 @@
('LICENSE_SHA256', 'license_sha256', '0d542e0c8804e39aa7f37eb00da5a762149dc682d7829451287e11b938e94594'),
)
LEGACY_ENGINE_COORDINATES = {
'0.183.348': '0.183.337',
'0.183.349': '0.183.337',
ENGINE_SHA: '7e45189f2b57097efc7929c04ddf7767aebbe027d1b9f90023aa6711522c5c80',
ENGINE_SOURCE: 'ba041fe312dfe97fc1e5144af576ddcf1b573d8e',
}
EXPECTED = {
COMPATIBILITY_CODE: (COMPATIBILITY, PUBLISHED_508),
'SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING': (DOCKER, 'ARG SERVER_RELEASE_TAG=v1.6.534'),
'SERVER_INCREMENTAL_RELEASE_DEFAULT_MISSING': (DOCKER, 'ARG SERVER_RELEASE_TAG=v1.6.535'),
'SERVER_INCREMENTAL_RELEASE_VERSION_MISSING': (DOCKER, 'org.opencontainers.image.version="${SERVER_RELEASE_TAG}"'),
'SERVER_INCREMENTAL_RELEASE_RUNTIME_VERSION_MISSING': (DOCKER, 'ENV CATTLE_RANCHER_SERVER_VERSION=${SERVER_RELEASE_TAG}'),
'SERVER_INCREMENTAL_WEB_CONSOLE_VERSION_MISSING': (DOCKER, 'ARG WEB_CONSOLE_RELEASE_TAG=1.6.189'),
Expand All @@ -58,8 +58,8 @@
'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_VERSION_MISSING': (BUILD, 'web_console_release_tag=${WEB_CONSOLE_RELEASE_TAG:-1.6.189}'),
'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_ARTIFACT_MISSING': (BUILD, 'web_console_artifact=${WEB_CONSOLE_ARTIFACT:-web-console-1.6.189.tar.gz}'),
'SERVER_INCREMENTAL_WEB_CONSOLE_BUILD_HASH_MISSING': (BUILD, 'web_console_artifact_sha256=${WEB_CONSOLE_ARTIFACT_SHA256:-' + WEB_SHA + '}'),
'SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING': (BUILD, 'image=${IMAGE:-pasturestack-validation/server:v1.6.534}'),
'SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING': (BUILD, 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.534}'),
'SERVER_INCREMENTAL_RELEASE_BUILD_VERSION_MISSING': (BUILD, 'image=${IMAGE:-pasturestack-validation/server:v1.6.535}'),
'SERVER_INCREMENTAL_RELEASE_BUILD_DEFAULT_MISSING': (BUILD, 'server_release_tag=${SERVER_RELEASE_TAG:-v1.6.535}'),
'SERVER_INCREMENTAL_RELEASE_BUILD_RUNTIME_VERSION_MISSING': (BUILD, 'CATTLE_RANCHER_SERVER_VERSION="${server_release_tag}"'),
'SERVER_WEB_CONSOLE_RUNTIME_VERSION_GATE_MISSING': (BUILD, 'test "$(cat "${web_root}/VERSION.txt")" = "${WEB_CONSOLE_RELEASE_TAG}"'),
'SERVER_VOLUME_NATIVE_READ_ONLY_BUILD_GATE_MISSING': (DOCKER, 'grep -F \'"volume.isNative" : "r"\' >/dev/null'),
Expand All @@ -80,18 +80,18 @@
CREATE_RESPONSE_CODES = ['SERVER_WEB_CREATE_IDENTITY_BUILD_GATE_MISSING','SERVER_WEB_CANONICAL_RECORD_BUILD_GATE_MISSING','SERVER_WEB_CREATE_IDENTITY_RUNTIME_GATE_MISSING','SERVER_WEB_CANONICAL_RECORD_RUNTIME_GATE_MISSING']
ENGINE_EXPECTED = {
'SERVER_INCREMENTAL_ENGINE_REPLACEMENT_MISSING': (DOCKER, 'release_engine_marker', (
'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.348',
'ARG ORCHESTRATION_ENGINE_RELEASE_TAG=v0.183.349',
'ARG ORCHESTRATION_ENGINE_ARTIFACT=cattle.jar',
'ARG ORCHESTRATION_ENGINE_ARTIFACT_SHA256=' + ENGINE_SHA,
'ARG ORCHESTRATION_ENGINE_COMMIT=' + ENGINE_SOURCE,
'ARG ORCHESTRATION_ENGINE_VERSION=0.183.348',
'ARG ORCHESTRATION_ENGINE_VERSION=0.183.349',
'grep -Fx "Implementation-Version: ${ORCHESTRATION_ENGINE_VERSION}"',
'cattle-resources-${ORCHESTRATION_ENGINE_VERSION}.jar',
'cattle-app-config-${ORCHESTRATION_ENGINE_VERSION}.jar',
'ENV CATTLE_CATTLE_VERSION=${ORCHESTRATION_ENGINE_RELEASE_TAG}',
)),
'SERVER_INCREMENTAL_ENGINE_BUILD_COORDINATE_MISSING': (BUILD, 'release_engine_build_marker', (
'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.348}',
'orchestration_engine_release_tag=${ORCHESTRATION_ENGINE_RELEASE_TAG:-v0.183.349}',
'orchestration_engine_artifact=${ORCHESTRATION_ENGINE_ARTIFACT:-cattle.jar}',
'orchestration_engine_artifact_sha256=${ORCHESTRATION_ENGINE_ARTIFACT_SHA256:-' + ENGINE_SHA + '}',
'orchestration_engine_commit=${ORCHESTRATION_ENGINE_COMMIT:-' + ENGINE_SOURCE + '}',
Expand Down Expand Up @@ -470,15 +470,15 @@ def verify(files, gate=GATE):
pipeline = r'(?:^|[;\n])\s*' + re.escape(marker) + r'(?=\s*(?:;|\n|$))'
if len(re.findall(pipeline, source)) != 1:
raise AssertionError('CURRENT_CATALOG_HASH_BYPASS')
if 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.534"' not in gate:
if 'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.535"' not in gate:
raise AssertionError('CURRENT_VEX_GATE_PIN_MISMATCH')
if '"$vendor_pending_fixture" v1.6.534 >/dev/null' not in gate:
if '"$vendor_pending_fixture" v1.6.535 >/dev/null' not in gate:
raise AssertionError('CURRENT_VENDOR_GATE_PIN_MISMATCH')
if json.loads(files[VEX]).get('@id') != 'https://github.com/PastureStack/server/security/openvex/v1.6.534':
if json.loads(files[VEX]).get('@id') != 'https://github.com/PastureStack/server/security/openvex/v1.6.535':
raise AssertionError('CURRENT_VEX_RELEASE_MISMATCH')
if json.loads(files[VENDOR]).get('release') != 'v1.6.534':
if json.loads(files[VENDOR]).get('release') != 'v1.6.535':
raise AssertionError('CURRENT_VENDOR_RELEASE_MISMATCH')
if 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.534 base=v1.6.460 engine=0.183.348 web_console=1.6.189 catalog_service=0.20.13 ' not in gate:
if 'SERVER_API_EXPLORER_PATCH_OK release=v1.6.535 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 ' not in gate:
raise AssertionError('CURRENT_SUMMARY_MISMATCH')
verify_incremental_contract(files, gate)

Expand All @@ -492,11 +492,11 @@ def previous_gate(gate=GATE):
if stale(marker) != marker:
replacements["'" + marker + "' "] = "'" + stale(marker) + "' "
replacements.update({
'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.534"':
'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.535"':
'and .["@id"] == "https://github.com/PastureStack/server/security/openvex/v1.6.521"',
'"$vendor_pending_fixture" v1.6.534 >/dev/null':
'"$vendor_pending_fixture" v1.6.535 >/dev/null':
'"$vendor_pending_fixture" v1.6.521 >/dev/null',
'SERVER_API_EXPLORER_PATCH_OK release=v1.6.534 base=v1.6.460 engine=0.183.348 web_console=1.6.189 catalog_service=0.20.13 ':
'SERVER_API_EXPLORER_PATCH_OK release=v1.6.535 base=v1.6.460 engine=0.183.349 web_console=1.6.189 catalog_service=0.20.13 ':
'SERVER_API_EXPLORER_PATCH_OK release=v1.6.521 base=v1.6.460 engine=0.183.340 web_console=1.6.181 catalog_service=0.20.12 ',
})
for marker, stale_marker in replacements.items():
Expand Down Expand Up @@ -988,7 +988,7 @@ def test_each_old_engine_coordinate_rejected(self):
self.assertGreater(checked, 0)

def test_historical_engine340_cannot_be_packaged(self):
old = {'0.183.348': '0.183.340',
old = {'0.183.349': '0.183.340',
ENGINE_SHA: '5e5a1b908b43bf3824fc3bb2108bd661cd5199ce9bcfd187e0b18b5608a38cea',
ENGINE_SOURCE: 'ff0a41e7676211043eb4f755a306a9e2a19abee1'}
checked = 0
Expand All @@ -1009,7 +1009,7 @@ def test_historical_engine340_cannot_be_packaged(self):


def test_immediately_previous_engine341_cannot_be_packaged(self):
old = {'0.183.348': '0.183.341',
old = {'0.183.349': '0.183.341',
ENGINE_SHA: '3ede1ad28b7a7e0754c4c953bd486162f7ffe0b2f76ce384ec485632af6b8e6d',
ENGINE_SOURCE: 'b245cf778479445ded0786d3898b03fea153212e'}
checked = 0
Expand All @@ -1030,7 +1030,7 @@ def test_immediately_previous_engine341_cannot_be_packaged(self):


def test_immediately_previous_engine342_cannot_be_packaged(self):
old = {'0.183.348': '0.183.342',
old = {'0.183.349': '0.183.342',
ENGINE_SHA: '3533f247392795329c92516a7966510aafbe81a52e3f922e5ec657a2071363b5',
ENGINE_SOURCE: 'ddae4bb8e12806f70816f5782cd999eccd0f2ce6'}
checked = 0
Expand All @@ -1051,7 +1051,7 @@ def test_immediately_previous_engine342_cannot_be_packaged(self):


def test_immediately_previous_engine343_cannot_be_packaged(self):
old = {'0.183.348': '0.183.343',
old = {'0.183.349': '0.183.343',
ENGINE_SHA: 'b29c0057f96dbae38bfe2c663c63bbe4c8b5c755b3090f39414aa51f9813025f',
ENGINE_SOURCE: '5aa9d8978c75a7fe63330453c399a92716d88568'}
checked = 0
Expand All @@ -1072,7 +1072,7 @@ def test_immediately_previous_engine343_cannot_be_packaged(self):


def test_immediately_previous_engine344_cannot_be_packaged(self):
old = {'0.183.348': '0.183.344',
old = {'0.183.349': '0.183.344',
ENGINE_SHA: 'ffafa4700156b74ec11bcae1b830738e49943f1a3b8b0565895ed6d7726eebf1',
ENGINE_SOURCE: '72c42e6f2000301fe03ffd2442fb9ee89aee120c'}
checked = 0
Expand All @@ -1092,7 +1092,7 @@ def test_immediately_previous_engine344_cannot_be_packaged(self):
self.assertGreater(checked, 0)

def test_immediately_previous_engine345_cannot_be_packaged(self):
old = {'0.183.348': '0.183.345',
old = {'0.183.349': '0.183.345',
ENGINE_SHA: '780263c4a884527fa80a28b998ad4bda88b9ad6002a687f9f074602ecad46e62',
ENGINE_SOURCE: 'd27d4ac73fa05ae43b9ae0c32875780e8a3765b1'}
checked = 0
Expand All @@ -1112,7 +1112,7 @@ def test_immediately_previous_engine345_cannot_be_packaged(self):
self.assertGreater(checked, 0)

def test_immediately_previous_engine346_cannot_be_packaged(self):
old = {'0.183.348': '0.183.346',
old = {'0.183.349': '0.183.346',
ENGINE_SHA: '9deeda5758b7f04135441a203092dd0308d90b65d25037b62ef4f9361d3cf806',
ENGINE_SOURCE: 'e250e4a17958216c30c1f5d0d31f7b6418a968d5'}
checked = 0
Expand Down
Loading