From ad43f4b6790c359e248710a39bca2f776d70be62 Mon Sep 17 00:00:00 2001
From: chen21019 <19357113+chen21019@users.noreply.github.com>
Date: Thu, 1 Oct 2026 13:03:36 +0800
Subject: [PATCH] fix: pin patched Jackson and cache runtime for Engine
0.183.328
---
.github/workflows/security-release-gate.yml | 56 +++++++++
README.md | 18 ++-
code/framework/api-pub-sub-jetty/pom.xml | 2 +-
code/framework/api-pub-sub/pom.xml | 2 +-
code/framework/api/pom.xml | 2 +-
code/framework/archaius/pom.xml | 2 +-
code/framework/async/pom.xml | 2 +-
code/framework/auditing/pom.xml | 2 +-
code/framework/db-loader/pom.xml | 2 +-
code/framework/deferred/pom.xml | 2 +-
code/framework/encryption/pom.xml | 2 +-
code/framework/engine/pom.xml | 2 +-
code/framework/eventing/pom.xml | 2 +-
code/framework/events/pom.xml | 2 +-
code/framework/extension-spring/pom.xml | 2 +-
code/framework/extension/pom.xml | 2 +-
code/framework/java-server/pom.xml | 2 +-
.../handler/BodyParserRequestHandlerTest.java | 86 +++++++++++++
code/framework/jmx/pom.xml | 2 +-
code/framework/jooq/pom.xml | 2 +-
code/framework/json/pom.xml | 2 +-
code/framework/launcher/pom.xml | 2 +-
code/framework/lock/pom.xml | 2 +-
code/framework/logback/pom.xml | 2 +-
code/framework/managed-context/pom.xml | 2 +-
code/framework/metrics/pom.xml | 2 +-
code/framework/module/pom.xml | 2 +-
code/framework/object/pom.xml | 2 +-
code/framework/pool/pom.xml | 2 +-
code/framework/resource-monitor/pom.xml | 2 +-
code/framework/schema/pom.xml | 2 +-
code/framework/server/pom.xml | 2 +-
code/framework/spring/pom.xml | 2 +-
code/framework/system-task/pom.xml | 2 +-
code/framework/token/pom.xml | 2 +-
code/framework/utils/pom.xml | 2 +-
code/iaas/agent-instance/pom.xml | 2 +-
code/iaas/agent-server/pom.xml | 2 +-
code/iaas/agent/pom.xml | 2 +-
code/iaas/allocator/pom.xml | 2 +-
code/iaas/api-logic/pom.xml | 2 +-
code/iaas/archaius-management/pom.xml | 2 +-
code/iaas/auth-logic/pom.xml | 2 +-
.../auth/mfa/WebAuthnConfigurationTest.java | 83 +++++++++++++
code/iaas/bootstrap/pom.xml | 2 +-
code/iaas/config-item/api/pom.xml | 2 +-
code/iaas/config-item/common/pom.xml | 2 +-
code/iaas/config-item/server/pom.xml | 2 +-
code/iaas/engine-jooq/pom.xml | 2 +-
code/iaas/events/pom.xml | 2 +-
code/iaas/external-handler/pom.xml | 2 +-
code/iaas/ha/pom.xml | 2 +-
code/iaas/healthcheck/pom.xml | 2 +-
code/iaas/labels/pom.xml | 2 +-
code/iaas/logic-common/pom.xml | 2 +-
code/iaas/logic/pom.xml | 2 +-
code/iaas/metadata/pom.xml | 2 +-
code/iaas/model/pom.xml | 2 +-
code/iaas/resource-pool/pom.xml | 2 +-
code/iaas/service-discovery/api/pom.xml | 2 +-
code/iaas/service-discovery/server/pom.xml | 2 +-
code/iaas/ssh-common/pom.xml | 2 +-
code/iaas/storage-service/pom.xml | 2 +-
code/iaas/task-jooq/pom.xml | 2 +-
code/implementation/activity-log/pom.xml | 2 +-
.../agent-instance-impl/pom.xml | 2 +-
code/implementation/docker/api/pom.xml | 2 +-
code/implementation/docker/common/pom.xml | 2 +-
code/implementation/docker/compute/pom.xml | 2 +-
code/implementation/docker/machine/pom.xml | 2 +-
code/implementation/docker/storage/pom.xml | 6 +-
code/implementation/extension-api/pom.xml | 2 +-
code/implementation/hazelcast/common/pom.xml | 2 +-
.../implementation/hazelcast/eventing/pom.xml | 2 +-
code/implementation/hazelcast/lock/pom.xml | 2 +-
code/implementation/host-api/pom.xml | 2 +-
code/implementation/host-stats/pom.xml | 2 +-
code/implementation/register/pom.xml | 2 +-
code/implementation/sample-setup/pom.xml | 2 +-
code/implementation/settings-api/pom.xml | 2 +-
.../simulator/agent-connection/pom.xml | 2 +-
code/implementation/simulator/storage/pom.xml | 2 +-
code/implementation/system-stack/pom.xml | 2 +-
code/implementation/vm/pom.xml | 2 +-
code/meta-parent/pom.xml | 8 +-
code/packaging/app-config/pom.xml | 2 +-
code/packaging/app/pom.xml | 2 +-
code/packaging/bundle/pom.xml | 2 +-
code/packaging/dev/pom.xml | 2 +-
code/packaging/meta/pom.xml | 2 +-
code/parent/pom.xml | 2 +-
.../orchestration-engine-0.183.328.md | 59 +++++++++
pom.xml | 2 +-
resources/pom.xml | 2 +-
scripts/build | 2 +-
scripts/check-cattle-dependency-hygiene | 27 +++--
scripts/check-cattle-runtime-jar-uniqueness | 21 +++-
...eck-cattle-runtime-jar-uniqueness-fixtures | 62 ++++++++--
scripts/check-pasturestack-source | 30 +++--
scripts/check-release-artifact | 2 +-
scripts/ci | 1 +
scripts/install-patched-hazelcast | 20 ++--
scripts/test-jackson-security-floors.py | 113 ++++++++++++++++++
third-party/HAZELCAST.md | 28 ++++-
104 files changed, 655 insertions(+), 141 deletions(-)
create mode 100644 docs/releases/orchestration-engine-0.183.328.md
create mode 100644 scripts/test-jackson-security-floors.py
diff --git a/.github/workflows/security-release-gate.yml b/.github/workflows/security-release-gate.yml
index 224b23b7b7..5b79f7d9d6 100644
--- a/.github/workflows/security-release-gate.yml
+++ b/.github/workflows/security-release-gate.yml
@@ -47,6 +47,62 @@ jobs:
cp dist/version evidence/engine-version.txt
sha256sum dist/artifacts/cattle.jar > evidence/cattle.jar.sha256
+ - name: Retain executed unit cases without properties or log content
+ shell: bash
+ run: |
+ set -euo pipefail
+ python3 - <<'PY'
+ import json
+ from pathlib import Path
+ import xml.etree.ElementTree as ET
+
+ required = {
+ 'io.github.ibuildthecloud.gdapi.request.handler.BodyParserRequestHandlerTest': {
+ 'mergeMapKeepsRequestParamsAndLetsBodyOverride',
+ 'mergeListRecursivelyMergesAllowedMapItems',
+ 'parsesObjectUnicodeAndAdditionalFieldsWithRealMapper',
+ 'parsesListWithRealMapperAndMergesObjectItems',
+ 'typedMapperIgnoresUnknownFieldsAndRoundTripsUnicode',
+ 'malformedJsonReturnsInvalidBodyContentBadRequest',
+ },
+ 'io.cattle.platform.iaas.api.auth.mfa.WebAuthnConfigurationTest': {
+ 'acceptsExactHttpsOriginAndRelyingParty',
+ 'acceptsHttpOnlyForLoopbackDevelopment',
+ 'rejectsInsecureLanOrigin', 'rejectsUnrelatedRelyingParty',
+ 'rejectsPublicSuffixAsRelyingParty',
+ 'objectConverterJsonRoundTripsNormalWebAuthnValues',
+ 'objectConverterCborRoundTripsNormalValuesAndBinaryData',
+ 'credentialDataStorageRoundTripPreservesPublicKeyAndCredentialId',
+ },
+ }
+ suites = []
+ observed = {}
+ for path in sorted(Path('code').glob('**/target/surefire-reports/TEST-*.xml')):
+ root = ET.parse(path).getroot()
+ cases = []
+ for case in root.findall('testcase'):
+ outcomes = [name for name in ('failure', 'error', 'skipped') if case.find(name) is not None]
+ record = {'class': case.get('classname'), 'name': case.get('name'),
+ 'status': outcomes[0] if outcomes else 'passed'}
+ cases.append(record)
+ if record['class'] in required:
+ key = (record['class'], record['name'])
+ assert key not in observed, ('duplicate required case', key)
+ observed[key] = record['status']
+ counts = {name: int(root.get(name, '0')) for name in ('tests', 'failures', 'errors', 'skipped')}
+ assert counts['tests'] == len(cases), ('report case count', str(path))
+ assert counts['failures'] == counts['errors'] == 0, ('failed unit suite', str(path))
+ suites.append({'report': path.as_posix(), 'counts': counts, 'cases': cases})
+ assert suites, 'No executed Surefire unit reports'
+ expected = {(name, case) for name, cases in required.items() for case in cases}
+ assert set(observed) == expected and set(observed.values()) == {'passed'}, 'Required cases missing, skipped or failed'
+ summary = {'source': Path('evidence/source-revision.txt').read_text().strip(),
+ 'suiteCount': len(suites), 'totals': {name: sum(s['counts'][name] for s in suites)
+ for name in ('tests', 'failures', 'errors', 'skipped')}, 'suites': suites}
+ Path('evidence/unit-test-results.json').write_text(json.dumps(summary, sort_keys=True, indent=2) + '\n')
+ print('UNIT_CASE_EVIDENCE_OK', summary['suiteCount'], summary['totals'])
+ PY
+
- name: Record resolved build inputs
shell: bash
run: |
diff --git a/README.md b/README.md
index a32d8b82ce..beb4624f1a 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,22 @@ and verifies its pinned digest and dependency metadata before installing it
into the build-local Maven repository. See
[`third-party/HAZELCAST.md`](third-party/HAZELCAST.md) for provenance.
+## Unreleased 0.183.328 candidate
+
+The source candidate updates platform Jackson to `2.22.3` and the isolated
+WebAuthn/logging Jackson line to `3.2.3`, with patchless annotations remaining
+`2.22`. These are the official patched versions for CVE-2026-91776 and
+CVE-2026-91777; see the [candidate note](docs/releases/orchestration-engine-0.183.328.md).
+The candidate pins the corresponding officially published
+[`distributed-cache-runtime` `5.7.5` artifact](https://github.com/PastureStack/distributed-cache-runtime/releases/tag/v5.7.5),
+because `5.7.4` embeds both older Jackson versions. The actual release JAR,
+source commit, checksum, and asset ID were read back and verified; see the
+[Cache provenance](third-party/HAZELCAST.md). Engine328 has not yet been built
+or published, and its seven new Java regression cases have not yet been
+compiled or executed. Cache's producer checks are not Engine validation.
+No Engine328 artifact, CI PASS, Server496 digest, or deployment is claimed.
+The published 327 provenance above remains historical and unchanged.
+
## Build and validation
Before publishing an Engine artifact or a Server image, run the complete
@@ -64,7 +80,7 @@ bash scripts/check-cattle-jdk25-full-package
After the gate passes, package and check the release artifact:
```sh
-ENGINE_VERSION=0.183.327 bash scripts/build --release
+ENGINE_VERSION=0.183.328 bash scripts/build --release
bash scripts/check-release-artifact dist/artifacts/cattle.jar
```
diff --git a/code/framework/api-pub-sub-jetty/pom.xml b/code/framework/api-pub-sub-jetty/pom.xml
index 4bbbe6abf3..127fdb75c9 100644
--- a/code/framework/api-pub-sub-jetty/pom.xml
+++ b/code/framework/api-pub-sub-jetty/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/api-pub-sub/pom.xml b/code/framework/api-pub-sub/pom.xml
index 26ecc4d2d5..65d17c4a4e 100644
--- a/code/framework/api-pub-sub/pom.xml
+++ b/code/framework/api-pub-sub/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/api/pom.xml b/code/framework/api/pom.xml
index 721afbc4e7..5a4b086333 100644
--- a/code/framework/api/pom.xml
+++ b/code/framework/api/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/archaius/pom.xml b/code/framework/archaius/pom.xml
index de1db46d2c..ad5ac3620f 100644
--- a/code/framework/archaius/pom.xml
+++ b/code/framework/archaius/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-meta-parent
- 0.183.327
+ 0.183.328
../../meta-parent/pom.xml
diff --git a/code/framework/async/pom.xml b/code/framework/async/pom.xml
index a4a4f31186..78b00ea6a0 100644
--- a/code/framework/async/pom.xml
+++ b/code/framework/async/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/auditing/pom.xml b/code/framework/auditing/pom.xml
index 8b11856ac8..d6f1a698e7 100644
--- a/code/framework/auditing/pom.xml
+++ b/code/framework/auditing/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/db-loader/pom.xml b/code/framework/db-loader/pom.xml
index cb17853ecd..61ca3a264b 100644
--- a/code/framework/db-loader/pom.xml
+++ b/code/framework/db-loader/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/deferred/pom.xml b/code/framework/deferred/pom.xml
index 221aaa0813..9fbf16ad91 100644
--- a/code/framework/deferred/pom.xml
+++ b/code/framework/deferred/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/encryption/pom.xml b/code/framework/encryption/pom.xml
index 31e83da012..1c4810719e 100644
--- a/code/framework/encryption/pom.xml
+++ b/code/framework/encryption/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/engine/pom.xml b/code/framework/engine/pom.xml
index bad41118ec..3bd8feaaae 100644
--- a/code/framework/engine/pom.xml
+++ b/code/framework/engine/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/eventing/pom.xml b/code/framework/eventing/pom.xml
index 935497b788..d0209a5dc4 100644
--- a/code/framework/eventing/pom.xml
+++ b/code/framework/eventing/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/events/pom.xml b/code/framework/events/pom.xml
index 4880c68e8a..baa5f84e59 100644
--- a/code/framework/events/pom.xml
+++ b/code/framework/events/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/extension-spring/pom.xml b/code/framework/extension-spring/pom.xml
index 6dd2d52cf8..bb31759c52 100644
--- a/code/framework/extension-spring/pom.xml
+++ b/code/framework/extension-spring/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/extension/pom.xml b/code/framework/extension/pom.xml
index c45484818d..b251c32eae 100644
--- a/code/framework/extension/pom.xml
+++ b/code/framework/extension/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/java-server/pom.xml b/code/framework/java-server/pom.xml
index 3e8ee9cf8d..4f3ff8994b 100644
--- a/code/framework/java-server/pom.xml
+++ b/code/framework/java-server/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/java-server/src/test/java/io/github/ibuildthecloud/gdapi/request/handler/BodyParserRequestHandlerTest.java b/code/framework/java-server/src/test/java/io/github/ibuildthecloud/gdapi/request/handler/BodyParserRequestHandlerTest.java
index 756bb92c0a..7704718dda 100644
--- a/code/framework/java-server/src/test/java/io/github/ibuildthecloud/gdapi/request/handler/BodyParserRequestHandlerTest.java
+++ b/code/framework/java-server/src/test/java/io/github/ibuildthecloud/gdapi/request/handler/BodyParserRequestHandlerTest.java
@@ -2,9 +2,18 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+import io.github.ibuildthecloud.gdapi.exception.ClientVisibleException;
+import io.github.ibuildthecloud.gdapi.json.JacksonMapper;
import io.github.ibuildthecloud.gdapi.request.ApiRequest;
+import io.github.ibuildthecloud.gdapi.util.ResponseCodes;
+import io.github.ibuildthecloud.gdapi.validation.ValidationErrorCodes;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -17,11 +26,15 @@ public class BodyParserRequestHandlerTest {
BodyParserRequestHandler handler;
ApiRequest request;
+ JacksonMapper mapper;
@Before
public void setUp() {
handler = new BodyParserRequestHandler();
handler.init();
+ mapper = new JacksonMapper();
+ mapper.init();
+ handler.setJsonMarshaller(mapper);
request = new ApiRequest(null, null);
Map params = new HashMap();
@@ -58,4 +71,77 @@ public void mergeListRecursivelyMergesAllowedMapItems() {
assertEquals("second", ((Map, ?>)result.get(1)).get("name"));
assertFalse(result.contains("ignored"));
}
+
+ @Test
+ public void parsesObjectUnicodeAndAdditionalFieldsWithRealMapper() throws Exception {
+ ApiRequest bodyRequest = jsonRequest("{\"name\":\"繁體中文/測試🙂\","
+ + "\"additionalField\":{\"enabled\":true,\"labels\":[\"甲\",\"乙\"]}}");
+
+ handler.handle(bodyRequest);
+
+ Map, ?> result = (Map, ?>)bodyRequest.getRequestObject();
+ assertEquals("繁體中文/測試🙂", result.get("name"));
+ assertEquals("query-value", result.get("queryOnly"));
+ Map, ?> additional = (Map, ?>)result.get("additionalField");
+ assertEquals(Boolean.TRUE, additional.get("enabled"));
+ assertEquals(Arrays.asList("甲", "乙"), additional.get("labels"));
+ }
+
+ @Test
+ public void parsesListWithRealMapperAndMergesObjectItems() throws Exception {
+ ApiRequest bodyRequest = jsonRequest("[{\"name\":\"first\"},\"ignored\","
+ + "{\"name\":\"second\",\"count\":2}]");
+
+ handler.handle(bodyRequest);
+
+ List> result = (List>)bodyRequest.getRequestObject();
+ assertEquals(2, result.size());
+ assertEquals("first", ((Map, ?>)result.get(0)).get("name"));
+ assertEquals("second", ((Map, ?>)result.get(1)).get("name"));
+ assertEquals(2, ((Map, ?>)result.get(1)).get("count"));
+ assertEquals("query-value", ((Map, ?>)result.get(1)).get("queryOnly"));
+ }
+
+ @Test
+ public void typedMapperIgnoresUnknownFieldsAndRoundTripsUnicode() throws Exception {
+ NameOnly value = mapper.readValue("{\"name\":\"名稱/✓\",\"futureField\":true}"
+ .getBytes(StandardCharsets.UTF_8), NameOnly.class);
+ assertEquals("名稱/✓", value.name);
+
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ mapper.writeValue(output, value);
+ Map, ?> result = mapper.readValue(output.toByteArray(), Map.class);
+ assertEquals("名稱/✓", result.get("name"));
+ assertFalse(result.containsKey("futureField"));
+ }
+
+ @Test
+ public void malformedJsonReturnsInvalidBodyContentBadRequest() throws Exception {
+ for (String malformed : Arrays.asList("{\"name\":", "[{\"name\":\"broken\"}")) {
+ try {
+ handler.handle(jsonRequest(malformed));
+ fail("Malformed JSON must not be accepted");
+ } catch (ClientVisibleException error) {
+ assertEquals(ResponseCodes.BAD_REQUEST, error.getStatus());
+ assertEquals(ValidationErrorCodes.INVALID_BODY_CONTENT, error.getCode());
+ }
+ }
+ }
+
+ private ApiRequest jsonRequest(String json) {
+ final byte[] content = json.getBytes(StandardCharsets.UTF_8);
+ ApiRequest bodyRequest = new ApiRequest(null, null) {
+ @Override
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(content);
+ }
+ };
+ bodyRequest.setMethod("POST");
+ bodyRequest.setRequestParams(request.getRequestParams());
+ return bodyRequest;
+ }
+
+ public static class NameOnly {
+ public String name;
+ }
}
diff --git a/code/framework/jmx/pom.xml b/code/framework/jmx/pom.xml
index 515a92ec32..0a247fa563 100644
--- a/code/framework/jmx/pom.xml
+++ b/code/framework/jmx/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/jooq/pom.xml b/code/framework/jooq/pom.xml
index e274086141..5741961d88 100644
--- a/code/framework/jooq/pom.xml
+++ b/code/framework/jooq/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/json/pom.xml b/code/framework/json/pom.xml
index ed1ee071b9..67a1e0b6fe 100644
--- a/code/framework/json/pom.xml
+++ b/code/framework/json/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/launcher/pom.xml b/code/framework/launcher/pom.xml
index 03e1dc8111..d430fe2309 100644
--- a/code/framework/launcher/pom.xml
+++ b/code/framework/launcher/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/lock/pom.xml b/code/framework/lock/pom.xml
index 93818f3b0d..a6fb652173 100644
--- a/code/framework/lock/pom.xml
+++ b/code/framework/lock/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/logback/pom.xml b/code/framework/logback/pom.xml
index 8101530b63..9990b83527 100644
--- a/code/framework/logback/pom.xml
+++ b/code/framework/logback/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-meta-parent
- 0.183.327
+ 0.183.328
../../meta-parent/pom.xml
diff --git a/code/framework/managed-context/pom.xml b/code/framework/managed-context/pom.xml
index 356238abf4..f2373f1509 100644
--- a/code/framework/managed-context/pom.xml
+++ b/code/framework/managed-context/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/metrics/pom.xml b/code/framework/metrics/pom.xml
index def5892f78..7cdd24fad8 100644
--- a/code/framework/metrics/pom.xml
+++ b/code/framework/metrics/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/module/pom.xml b/code/framework/module/pom.xml
index 7c36984612..4ddd3d4462 100644
--- a/code/framework/module/pom.xml
+++ b/code/framework/module/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/object/pom.xml b/code/framework/object/pom.xml
index 61280b2654..f6b6c68d2d 100644
--- a/code/framework/object/pom.xml
+++ b/code/framework/object/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/pool/pom.xml b/code/framework/pool/pom.xml
index aeb1356b4e..27374c921d 100644
--- a/code/framework/pool/pom.xml
+++ b/code/framework/pool/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/resource-monitor/pom.xml b/code/framework/resource-monitor/pom.xml
index 8682b7e64d..d558ab39f2 100644
--- a/code/framework/resource-monitor/pom.xml
+++ b/code/framework/resource-monitor/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/schema/pom.xml b/code/framework/schema/pom.xml
index 61db3db272..6a67489b51 100644
--- a/code/framework/schema/pom.xml
+++ b/code/framework/schema/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/server/pom.xml b/code/framework/server/pom.xml
index 9b51ae6d91..62ee69471f 100644
--- a/code/framework/server/pom.xml
+++ b/code/framework/server/pom.xml
@@ -4,7 +4,7 @@
cattle-meta-parent
io.cattle
- 0.183.327
+ 0.183.328
../../meta-parent/pom.xml
diff --git a/code/framework/spring/pom.xml b/code/framework/spring/pom.xml
index 2726e32570..847d3e0c2d 100644
--- a/code/framework/spring/pom.xml
+++ b/code/framework/spring/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/system-task/pom.xml b/code/framework/system-task/pom.xml
index 9ed64beb0d..211022d386 100644
--- a/code/framework/system-task/pom.xml
+++ b/code/framework/system-task/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/token/pom.xml b/code/framework/token/pom.xml
index 729b879ed0..8854e7f7bf 100644
--- a/code/framework/token/pom.xml
+++ b/code/framework/token/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/framework/utils/pom.xml b/code/framework/utils/pom.xml
index 100f13e57b..6f2da549cb 100644
--- a/code/framework/utils/pom.xml
+++ b/code/framework/utils/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/agent-instance/pom.xml b/code/iaas/agent-instance/pom.xml
index 7086c7f511..4352169450 100644
--- a/code/iaas/agent-instance/pom.xml
+++ b/code/iaas/agent-instance/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/agent-server/pom.xml b/code/iaas/agent-server/pom.xml
index 6f2bf0aa3b..cb4533443e 100644
--- a/code/iaas/agent-server/pom.xml
+++ b/code/iaas/agent-server/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/agent/pom.xml b/code/iaas/agent/pom.xml
index 76a925744c..82e3570b68 100644
--- a/code/iaas/agent/pom.xml
+++ b/code/iaas/agent/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/allocator/pom.xml b/code/iaas/allocator/pom.xml
index 6b25fc2916..b1554f586d 100644
--- a/code/iaas/allocator/pom.xml
+++ b/code/iaas/allocator/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/api-logic/pom.xml b/code/iaas/api-logic/pom.xml
index a828cf560b..2e8eb62e41 100644
--- a/code/iaas/api-logic/pom.xml
+++ b/code/iaas/api-logic/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/archaius-management/pom.xml b/code/iaas/archaius-management/pom.xml
index 255180e1ac..4e85f1bb84 100644
--- a/code/iaas/archaius-management/pom.xml
+++ b/code/iaas/archaius-management/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/auth-logic/pom.xml b/code/iaas/auth-logic/pom.xml
index 308227f40f..9e541cb00f 100644
--- a/code/iaas/auth-logic/pom.xml
+++ b/code/iaas/auth-logic/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/auth-logic/src/test/java/io/cattle/platform/iaas/api/auth/mfa/WebAuthnConfigurationTest.java b/code/iaas/auth-logic/src/test/java/io/cattle/platform/iaas/api/auth/mfa/WebAuthnConfigurationTest.java
index 0282b01154..3ac94243b6 100644
--- a/code/iaas/auth-logic/src/test/java/io/cattle/platform/iaas/api/auth/mfa/WebAuthnConfigurationTest.java
+++ b/code/iaas/auth-logic/src/test/java/io/cattle/platform/iaas/api/auth/mfa/WebAuthnConfigurationTest.java
@@ -1,9 +1,29 @@
package io.cattle.platform.iaas.api.auth.mfa;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import io.github.ibuildthecloud.gdapi.exception.ClientVisibleException;
+import java.security.KeyPairGenerator;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
import org.junit.Test;
+import com.webauthn4j.converter.AttestedCredentialDataConverter;
+import com.webauthn4j.converter.util.ObjectConverter;
+import com.webauthn4j.data.attestation.authenticator.AAGUID;
+import com.webauthn4j.data.attestation.authenticator.AttestedCredentialData;
+import com.webauthn4j.data.attestation.authenticator.EC2COSEKey;
+import com.webauthn4j.data.attestation.statement.COSEAlgorithmIdentifier;
+
public class WebAuthnConfigurationTest {
private final WebAuthnService service = new WebAuthnService();
@@ -35,6 +55,69 @@ public void rejectsPublicSuffixAsRelyingParty() {
service.validateConfiguration(policy("co.uk", "https://console.co.uk"));
}
+ @Test
+ public void objectConverterJsonRoundTripsNormalWebAuthnValues() {
+ ObjectConverter converter = new ObjectConverter();
+ Map fixture = converterFixture();
+
+ String json = converter.getJsonConverter().writeValueAsString(fixture);
+ Map, ?> restored = converter.getJsonConverter().readValue(json, Map.class);
+
+ assertEquals(fixture, restored);
+ }
+
+ @Test
+ public void objectConverterCborRoundTripsNormalValuesAndBinaryData() {
+ ObjectConverter converter = new ObjectConverter();
+ Map fixture = converterFixture();
+ byte[] binary = new byte[] { 0, 1, 127, (byte)128, (byte)255 };
+ fixture.put("binary", binary);
+
+ byte[] cbor = converter.getCborConverter().writeValueAsBytes(fixture);
+ Map, ?> restored = converter.getCborConverter().readValue(cbor, Map.class);
+
+ assertEquals(fixture.size(), restored.size());
+ assertEquals(fixture.get("name"), restored.get("name"));
+ assertEquals(fixture.get("counter"), restored.get("counter"));
+ assertEquals(fixture.get("transports"), restored.get("transports"));
+ assertEquals(fixture.get("verified"), restored.get("verified"));
+ assertArrayEquals(binary, (byte[])restored.get("binary"));
+ }
+
+ @Test
+ public void credentialDataStorageRoundTripPreservesPublicKeyAndCredentialId() throws Exception {
+ // Exercise the same CBOR converter and base64url storage representation as WebAuthnService.
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
+ generator.initialize(new ECGenParameterSpec("secp256r1"));
+ EC2COSEKey publicKey = EC2COSEKey.create(
+ (ECPublicKey)generator.generateKeyPair().getPublic(), COSEAlgorithmIdentifier.ES256);
+ byte[] credentialId = new byte[] { 0, 1, 2, 127, (byte)128, (byte)255 };
+ AttestedCredentialData fixture = new AttestedCredentialData(AAGUID.ZERO, credentialId, publicKey);
+ AttestedCredentialDataConverter converter = new AttestedCredentialDataConverter(new ObjectConverter());
+
+ byte[] original = converter.convert(fixture);
+ String stored = Base64.getUrlEncoder().withoutPadding().encodeToString(original);
+ AttestedCredentialData restored = converter.convert(Base64.getUrlDecoder().decode(stored));
+
+ assertEquals(fixture, restored);
+ assertArrayEquals(credentialId, restored.getCredentialId());
+ assertEquals(AAGUID.ZERO, restored.getAaguid());
+ assertEquals(COSEAlgorithmIdentifier.ES256, restored.getCOSEKey().getAlgorithm());
+ assertTrue(restored.getCOSEKey().hasPublicKey());
+ assertFalse(restored.getCOSEKey().hasPrivateKey());
+ assertArrayEquals(publicKey.getPublicKey().getEncoded(), restored.getCOSEKey().getPublicKey().getEncoded());
+ assertArrayEquals(original, converter.convert(restored));
+ }
+
+ private Map converterFixture() {
+ Map fixture = new LinkedHashMap<>();
+ fixture.put("name", "測試憑證/✓");
+ fixture.put("counter", 7);
+ fixture.put("transports", Arrays.asList("internal", "usb"));
+ fixture.put("verified", true);
+ return fixture;
+ }
+
private MfaPolicy policy(String rpId, String origin) {
return new MfaPolicy("optional", 5, rpId, origin, "PastureStack", "PastureStack");
}
diff --git a/code/iaas/bootstrap/pom.xml b/code/iaas/bootstrap/pom.xml
index 3d72dd67e5..1bd2e65bf9 100644
--- a/code/iaas/bootstrap/pom.xml
+++ b/code/iaas/bootstrap/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/config-item/api/pom.xml b/code/iaas/config-item/api/pom.xml
index 747c13c17c..ef45191dcc 100644
--- a/code/iaas/config-item/api/pom.xml
+++ b/code/iaas/config-item/api/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/iaas/config-item/common/pom.xml b/code/iaas/config-item/common/pom.xml
index 4cf0d22421..297a1631dc 100644
--- a/code/iaas/config-item/common/pom.xml
+++ b/code/iaas/config-item/common/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/iaas/config-item/server/pom.xml b/code/iaas/config-item/server/pom.xml
index f6e8deedc1..b22ba12d8b 100644
--- a/code/iaas/config-item/server/pom.xml
+++ b/code/iaas/config-item/server/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/iaas/engine-jooq/pom.xml b/code/iaas/engine-jooq/pom.xml
index c72080380e..3bcd1ac9e1 100644
--- a/code/iaas/engine-jooq/pom.xml
+++ b/code/iaas/engine-jooq/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/events/pom.xml b/code/iaas/events/pom.xml
index dac16a85c5..c341f18a31 100644
--- a/code/iaas/events/pom.xml
+++ b/code/iaas/events/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/external-handler/pom.xml b/code/iaas/external-handler/pom.xml
index 53122c7c3a..f850e3061a 100644
--- a/code/iaas/external-handler/pom.xml
+++ b/code/iaas/external-handler/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/ha/pom.xml b/code/iaas/ha/pom.xml
index 52dfbe94b6..f65cc3a2fa 100644
--- a/code/iaas/ha/pom.xml
+++ b/code/iaas/ha/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/healthcheck/pom.xml b/code/iaas/healthcheck/pom.xml
index 9b166c96c6..a30c264090 100644
--- a/code/iaas/healthcheck/pom.xml
+++ b/code/iaas/healthcheck/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/labels/pom.xml b/code/iaas/labels/pom.xml
index 254f814924..d1886d20a5 100644
--- a/code/iaas/labels/pom.xml
+++ b/code/iaas/labels/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/logic-common/pom.xml b/code/iaas/logic-common/pom.xml
index 989ad15442..f48905a6e4 100644
--- a/code/iaas/logic-common/pom.xml
+++ b/code/iaas/logic-common/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/logic/pom.xml b/code/iaas/logic/pom.xml
index 07f8b79698..cbf41e034f 100644
--- a/code/iaas/logic/pom.xml
+++ b/code/iaas/logic/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/metadata/pom.xml b/code/iaas/metadata/pom.xml
index 497a0d5173..ea96c2f2a7 100644
--- a/code/iaas/metadata/pom.xml
+++ b/code/iaas/metadata/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/model/pom.xml b/code/iaas/model/pom.xml
index 5a9f2a3b2c..68407581a7 100644
--- a/code/iaas/model/pom.xml
+++ b/code/iaas/model/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/resource-pool/pom.xml b/code/iaas/resource-pool/pom.xml
index eda57f52cd..5c7e7cf91d 100644
--- a/code/iaas/resource-pool/pom.xml
+++ b/code/iaas/resource-pool/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/service-discovery/api/pom.xml b/code/iaas/service-discovery/api/pom.xml
index c51ef923b8..e5a2799e51 100644
--- a/code/iaas/service-discovery/api/pom.xml
+++ b/code/iaas/service-discovery/api/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/iaas/service-discovery/server/pom.xml b/code/iaas/service-discovery/server/pom.xml
index ee3745b380..c3b012215c 100644
--- a/code/iaas/service-discovery/server/pom.xml
+++ b/code/iaas/service-discovery/server/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/iaas/ssh-common/pom.xml b/code/iaas/ssh-common/pom.xml
index 3a19993824..5cad182a86 100644
--- a/code/iaas/ssh-common/pom.xml
+++ b/code/iaas/ssh-common/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/storage-service/pom.xml b/code/iaas/storage-service/pom.xml
index 83818707a1..b3f2b33fbc 100644
--- a/code/iaas/storage-service/pom.xml
+++ b/code/iaas/storage-service/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/iaas/task-jooq/pom.xml b/code/iaas/task-jooq/pom.xml
index d6873a78e2..38e74054df 100644
--- a/code/iaas/task-jooq/pom.xml
+++ b/code/iaas/task-jooq/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/activity-log/pom.xml b/code/implementation/activity-log/pom.xml
index 94a147b2d4..257a239a75 100644
--- a/code/implementation/activity-log/pom.xml
+++ b/code/implementation/activity-log/pom.xml
@@ -5,7 +5,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/agent-instance-impl/pom.xml b/code/implementation/agent-instance-impl/pom.xml
index 36c80ef81d..df51b05e74 100644
--- a/code/implementation/agent-instance-impl/pom.xml
+++ b/code/implementation/agent-instance-impl/pom.xml
@@ -3,7 +3,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
cattle-agent-instance-impl
diff --git a/code/implementation/docker/api/pom.xml b/code/implementation/docker/api/pom.xml
index eeb938aae5..c852088b8a 100644
--- a/code/implementation/docker/api/pom.xml
+++ b/code/implementation/docker/api/pom.xml
@@ -5,7 +5,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/docker/common/pom.xml b/code/implementation/docker/common/pom.xml
index a13ed71cc7..20e2496010 100644
--- a/code/implementation/docker/common/pom.xml
+++ b/code/implementation/docker/common/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/docker/compute/pom.xml b/code/implementation/docker/compute/pom.xml
index ad857a172a..005c918ce0 100644
--- a/code/implementation/docker/compute/pom.xml
+++ b/code/implementation/docker/compute/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/docker/machine/pom.xml b/code/implementation/docker/machine/pom.xml
index e32579c381..fff87ad881 100644
--- a/code/implementation/docker/machine/pom.xml
+++ b/code/implementation/docker/machine/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/docker/storage/pom.xml b/code/implementation/docker/storage/pom.xml
index 28a457b526..4f24761f2f 100644
--- a/code/implementation/docker/storage/pom.xml
+++ b/code/implementation/docker/storage/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
@@ -21,12 +21,12 @@
io.cattle
cattle-docker-common
- 0.183.327
+ 0.183.328
io.cattle
cattle-iaas-allocator
- 0.183.327
+ 0.183.328
diff --git a/code/implementation/extension-api/pom.xml b/code/implementation/extension-api/pom.xml
index cccf48b638..b052faffe6 100644
--- a/code/implementation/extension-api/pom.xml
+++ b/code/implementation/extension-api/pom.xml
@@ -3,7 +3,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
cattle-extension-api
diff --git a/code/implementation/hazelcast/common/pom.xml b/code/implementation/hazelcast/common/pom.xml
index 58c38f4a44..facdafddd6 100644
--- a/code/implementation/hazelcast/common/pom.xml
+++ b/code/implementation/hazelcast/common/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/hazelcast/eventing/pom.xml b/code/implementation/hazelcast/eventing/pom.xml
index 9508ab200d..07ba98745b 100644
--- a/code/implementation/hazelcast/eventing/pom.xml
+++ b/code/implementation/hazelcast/eventing/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/hazelcast/lock/pom.xml b/code/implementation/hazelcast/lock/pom.xml
index e69a40b1a6..5700f8c2ba 100644
--- a/code/implementation/hazelcast/lock/pom.xml
+++ b/code/implementation/hazelcast/lock/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/host-api/pom.xml b/code/implementation/host-api/pom.xml
index d67abfac3c..07be1b8caa 100644
--- a/code/implementation/host-api/pom.xml
+++ b/code/implementation/host-api/pom.xml
@@ -5,7 +5,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/host-stats/pom.xml b/code/implementation/host-stats/pom.xml
index 9802e05fad..d22f2301ee 100644
--- a/code/implementation/host-stats/pom.xml
+++ b/code/implementation/host-stats/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/register/pom.xml b/code/implementation/register/pom.xml
index a825b2aeb7..889eddf3c6 100644
--- a/code/implementation/register/pom.xml
+++ b/code/implementation/register/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/sample-setup/pom.xml b/code/implementation/sample-setup/pom.xml
index 461ec04a0e..11c11d8292 100644
--- a/code/implementation/sample-setup/pom.xml
+++ b/code/implementation/sample-setup/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/settings-api/pom.xml b/code/implementation/settings-api/pom.xml
index 6c04deb401..8a10b9d2c7 100644
--- a/code/implementation/settings-api/pom.xml
+++ b/code/implementation/settings-api/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/simulator/agent-connection/pom.xml b/code/implementation/simulator/agent-connection/pom.xml
index 9c151a0340..26fff2feaf 100644
--- a/code/implementation/simulator/agent-connection/pom.xml
+++ b/code/implementation/simulator/agent-connection/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/simulator/storage/pom.xml b/code/implementation/simulator/storage/pom.xml
index 2c5b3b8f47..db80e23608 100644
--- a/code/implementation/simulator/storage/pom.xml
+++ b/code/implementation/simulator/storage/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../../parent/pom.xml
diff --git a/code/implementation/system-stack/pom.xml b/code/implementation/system-stack/pom.xml
index f04f976c6f..6b08b149d6 100644
--- a/code/implementation/system-stack/pom.xml
+++ b/code/implementation/system-stack/pom.xml
@@ -5,7 +5,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/implementation/vm/pom.xml b/code/implementation/vm/pom.xml
index 6b9a39aefc..6c26be22e1 100644
--- a/code/implementation/vm/pom.xml
+++ b/code/implementation/vm/pom.xml
@@ -3,7 +3,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
cattle-vm
diff --git a/code/meta-parent/pom.xml b/code/meta-parent/pom.xml
index 5b09ae6034..38669d5791 100644
--- a/code/meta-parent/pom.xml
+++ b/code/meta-parent/pom.xml
@@ -9,7 +9,7 @@
4.0.0
io.cattle
cattle-meta-parent
- 0.183.327
+ 0.183.328
pom
PastureStack Orchestration Engine
Compatibility orchestration engine for the PastureStack server.
@@ -43,18 +43,18 @@
12.1.12
3.21.7
- 2.22.2
+ 2.22.3
2.22
7.0.9
4.2.39
- 5.7.4
+ 5.7.5
3.33.0-GA
3.7.1
1.6.3
2.0.18
9.0
0.31.9.RELEASE
- 3.2.2
+ 3.2.3
2.1.5
2.0.5
1.4.0
diff --git a/code/packaging/app-config/pom.xml b/code/packaging/app-config/pom.xml
index 95f715877d..7108c1dd37 100644
--- a/code/packaging/app-config/pom.xml
+++ b/code/packaging/app-config/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
jar
diff --git a/code/packaging/app/pom.xml b/code/packaging/app/pom.xml
index 2d56769482..40e24b947f 100644
--- a/code/packaging/app/pom.xml
+++ b/code/packaging/app/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
war
diff --git a/code/packaging/bundle/pom.xml b/code/packaging/bundle/pom.xml
index 2dca67f431..6ce9d9279f 100644
--- a/code/packaging/bundle/pom.xml
+++ b/code/packaging/bundle/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/packaging/dev/pom.xml b/code/packaging/dev/pom.xml
index 3318684384..f7828b12b9 100644
--- a/code/packaging/dev/pom.xml
+++ b/code/packaging/dev/pom.xml
@@ -4,7 +4,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/packaging/meta/pom.xml b/code/packaging/meta/pom.xml
index 0505f68506..e4fe63274b 100644
--- a/code/packaging/meta/pom.xml
+++ b/code/packaging/meta/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../../parent/pom.xml
diff --git a/code/parent/pom.xml b/code/parent/pom.xml
index 89eb2cf98b..52a25b01c7 100644
--- a/code/parent/pom.xml
+++ b/code/parent/pom.xml
@@ -5,7 +5,7 @@
io.cattle
cattle-meta-parent
../meta-parent/pom.xml
- 0.183.327
+ 0.183.328
pom
diff --git a/docs/releases/orchestration-engine-0.183.328.md b/docs/releases/orchestration-engine-0.183.328.md
new file mode 100644
index 0000000000..3b2d80640d
--- /dev/null
+++ b/docs/releases/orchestration-engine-0.183.328.md
@@ -0,0 +1,59 @@
+# Orchestration Engine 0.183.328 candidate — not released
+
+## Scope and official correction
+
+This source-only candidate updates the platform `com.fasterxml.jackson`
+runtime from `2.22.2` to `2.22.3` and the isolated `tools.jackson` runtime from
+`3.2.2` to `3.2.3`. Patchless `jackson-annotations` stays `2.22`.
+The maintainer advisories for
+[CVE-2026-91776](https://github.com/FasterXML/jackson-databind/security/advisories/GHSA-wv8q-qhhj-9h54)
+and [CVE-2026-91777](https://github.com/FasterXML/jackson-databind/security/advisories/GHSA-cxp5-3px4-pw24)
+list these same-line patched versions. Dependency presence and release-gate
+failure are established; this note does not assert a tested exploit against
+the deployed service.
+
+Both runtime generations remain necessary: platform JSON uses Jackson2,
+while WebAuthn4J and logstash-logback-encoder use Jackson3. The packaged gate
+requires exactly one patched core and databind JAR per generation, with
+disjoint class namespaces. Older patch pairs, missing generations, duplicate
+payloads, and overlapping namespaces are rejected.
+Multi-release class paths are normalized before namespace and overlap checks;
+module descriptors are excluded because they describe distinct modules rather
+than duplicate loadable classes. Regression fixtures exercise root and
+multi-release foreign classes for both core/databind generations.
+
+## Embedded copy and verified Cache provenance
+
+The Server496 failed-run scan also identifies both older databind versions
+inside `hazelcast-5.7.4.jar`; updating Engine dependencyManagement alone is not
+sufficient. The dedicated cache producer has officially published `5.7.5`
+with the same Jackson patch versions. Published-asset readback verified source
+`a9aea563870201462dc24f778a06279a08ed5841`, GitHub asset `602470126`, size
+`23,852,246` bytes, and JAR SHA-256
+`0f536a9c7bcd00f2369586fb6ca1606f7e45f3225e24795d10d38397051c8715`.
+The installer and source oracle pin those exact identities; see the
+[Cache provenance](../../third-party/HAZELCAST.md) for the signed numeric tag
+and producer build/security/CodeQL evidence. Engine consumes an official,
+checksum-pinned artifact, not a second local fork.
+
+Engine328 has not yet been built or published. The successful Cache producer
+checks do not establish Engine compatibility or replace its pending consumer
+tests. There is no Engine328 release artifact, source/build/SBOM/runtime PASS,
+or Server496 image digest at this stage.
+Server496 run `36812661669` remains failed; its original evidence is not changed.
+The published Engine327 and its release notes remain historical records.
+
+## Required Engine328 validation before publication
+
+Run the dependency and exact dual-namespace fixture gates, then the existing
+`JacksonJsonMapperTest` and MFA/WebAuthn-adjacent tests. Four new
+`BodyParserRequestHandlerTest` cases cover the real gdapi mapper, object/list
+merging, Unicode, unknown fields, and malformed JSON returning 400. Three new
+`WebAuthnConfigurationTest` cases cover WebAuthn4J JSON/CBOR and the credential
+data/base64url storage roundtrip. These seven Java cases have not yet been
+compiled or executed; configuration-only tests are not a full Passkey login.
+Review effective POM
+and dependency tree for both patched lines. Before publishing, the existing
+full package, actual JAR inventory/SBOM/security, and standalone runtime gates
+remain required. No database or QA authentication is part of this candidate
+preparation, and no security gate or VEX exception is relaxed.
diff --git a/pom.xml b/pom.xml
index ef12e1d0c3..f1e2b71c3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
io.cattle
cattle-parent
- 0.183.327
+ 0.183.328
code/parent/pom.xml
cattle
diff --git a/resources/pom.xml b/resources/pom.xml
index 4c0d6c3df8..2cafb59ae7 100644
--- a/resources/pom.xml
+++ b/resources/pom.xml
@@ -4,7 +4,7 @@
cattle-parent
io.cattle
- 0.183.327
+ 0.183.328
../code/parent/pom.xml
diff --git a/scripts/build b/scripts/build
index e522a06c40..aee980f2b6 100755
--- a/scripts/build
+++ b/scripts/build
@@ -16,7 +16,7 @@ fi
SOURCE_REVISION=${SOURCE_REVISION:-$(git rev-parse HEAD)}
SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH:-$(git show -s --format=%ct HEAD)}
-ENGINE_VERSION=${ENGINE_VERSION:-0.183.327}
+ENGINE_VERSION=${ENGINE_VERSION:-0.183.328}
case "$SOURCE_REVISION" in
''|*[!0-9a-f]*)
diff --git a/scripts/check-cattle-dependency-hygiene b/scripts/check-cattle-dependency-hygiene
index bccf4e6faa..171681578a 100755
--- a/scripts/check-cattle-dependency-hygiene
+++ b/scripts/check-cattle-dependency-hygiene
@@ -196,12 +196,12 @@ import xml.etree.ElementTree as ET
from pathlib import Path
NS = {"m": "http://maven.apache.org/POM/4.0.0"}
-JACKSON2_FLOOR = (2, 22, 0)
-JACKSON2_FLOOR_TEXT = "2.22.0"
+JACKSON2_FLOOR = (2, 22, 3)
+JACKSON2_FLOOR_TEXT = "2.22.3"
JACKSON2_ANNOTATIONS_FLOOR = (2, 22, 0)
JACKSON2_ANNOTATIONS_FLOOR_TEXT = "2.22"
-JACKSON3_WEBAUTHN_FLOOR = (3, 2, 1)
-JACKSON3_WEBAUTHN_FLOOR_TEXT = "3.2.1"
+JACKSON3_WEBAUTHN_FLOOR = (3, 2, 3)
+JACKSON3_WEBAUTHN_FLOOR_TEXT = "3.2.3"
JACKSON3_WEBAUTHN_COORDINATES = {
("tools.jackson.core", "jackson-core"),
("tools.jackson.core", "jackson-databind"),
@@ -310,7 +310,7 @@ sys.exit(0)
PY
)
if [ -n "$jackson_security_floor_dependencies" ]; then
- echo "Blocked Jackson dependency outside the maintained runtime line found in Maven POMs; keep the platform on Jackson 2.22+ and the explicitly pinned WebAuthn tools.jackson boundary on stable 3.2.1+" >&2
+ echo "Blocked Jackson dependency outside the maintained runtime line found in Maven POMs; keep the platform on Jackson 2.22.3+ and the explicitly pinned WebAuthn tools.jackson boundary on stable 3.2.3+" >&2
echo "$jackson_security_floor_dependencies" >&2
fail=1
fi
@@ -4178,8 +4178,9 @@ import re
import sys
from pathlib import Path
-JACKSON2_FLOOR = (2, 22, 0)
-JACKSON3_FLOOR = (3, 2, 1)
+JACKSON2_FLOOR = (2, 22, 3)
+JACKSON2_ANNOTATIONS_FLOOR = (2, 22, 0)
+JACKSON3_FLOOR = (3, 2, 3)
UNREVIEWED_QUALIFIER = re.compile(r"(?:^|[.-])(alpha|beta|snapshot|rc|b\d+|m\d+|mr|milestone|pr\d+)(?:[.-]|\d|$)", re.IGNORECASE)
root = Path("code/packaging/app/target")
failures = []
@@ -4196,10 +4197,12 @@ if root.exists():
version = (int(major), int(minor), int(patch or "0"))
if artifact == "jackson-annotations" and version[0] == 2 and version[1] >= 20 and patch is not None:
failures.append(f"{path}: Jackson 2 annotations jar uses a patch version; use the patchless 2.20+ annotations line")
- if version[0] == 2 and version < JACKSON2_FLOOR:
- failures.append(f"{path}: Jackson 2 < 2.22.0")
+ jackson2_floor = JACKSON2_ANNOTATIONS_FLOOR if artifact == "jackson-annotations" else JACKSON2_FLOOR
+ if version[0] == 2 and version < jackson2_floor:
+ floor_text = "2.22" if artifact == "jackson-annotations" else "2.22.3"
+ failures.append(f"{path}: Jackson 2 < {floor_text}")
elif version[0] == 3 and version < JACKSON3_FLOOR:
- failures.append(f"{path}: Jackson 3 < 3.2.1")
+ failures.append(f"{path}: Jackson 3 < 3.2.3")
elif version[0] not in (2, 3):
failures.append(f"{path}: unsupported Jackson major {version[0]}")
if UNREVIEWED_QUALIFIER.search(qualifier):
@@ -4210,7 +4213,7 @@ sys.exit(0)
PY
)
if [ -n "$jackson_security_floor_jars" ]; then
- echo "Blocked Jackson jar below maintained stable floor packaged in app; keep Jackson 2 at 2.22.0+ and Jackson 3 at 3.2.1+ without unreviewed qualifiers" >&2
+ echo "Blocked Jackson jar below maintained stable floor packaged in app; keep Jackson 2 at 2.22.3+ (annotations 2.22) and Jackson 3 at 3.2.3+ without unreviewed qualifiers" >&2
echo "$jackson_security_floor_jars" >&2
fail=1
fi
@@ -6868,7 +6871,7 @@ echo "Resolved in the jOOQ compatibility slice:"
echo "- jOOQ runtime, metadata, codegen, and JPA extension artifacts stay on reviewed stable 3.21.x at 3.21.7+; unreviewed qualifiers and line jumps require explicit record-mapping/codegen review."
echo "Resolved in the Jackson compatibility slice:"
echo "- Legacy Codehaus Jackson 1.x dependencies, imports, and packaged jars are blocked; maintained Jackson 2/3 artifacts own JSON processing."
-echo "- Jackson 2 cannot drop below stable 2.22.0 with annotations 2.22, and Jackson 3 cannot drop below stable 3.2.1; unreviewed qualifiers require explicit JSON compatibility review."
+echo "- Jackson 2 cannot drop below stable 2.22.3 with annotations 2.22, and Jackson 3 cannot drop below stable 3.2.3; unreviewed qualifiers require explicit JSON compatibility review."
echo "- The platform remains on com.fasterxml Jackson 2; WebAuthn4J and logstash-logback-encoder use the pinned tools.jackson 3.2 line, and packaged gates verify the two generations have exact, disjoint class namespaces."
echo "Resolved in the serialization helper compatibility slice:"
echo "- Legacy XStream/json-lib/EZMorph/cglib-nodep/asm-all dependencies, imports, and packaged jars are blocked; maintained Jackson/JDK/modern ASM-family paths require explicit compatibility review."
diff --git a/scripts/check-cattle-runtime-jar-uniqueness b/scripts/check-cattle-runtime-jar-uniqueness
index edfed60d6d..bc599d7001 100755
--- a/scripts/check-cattle-runtime-jar-uniqueness
+++ b/scripts/check-cattle-runtime-jar-uniqueness
@@ -99,12 +99,12 @@ legacy_metrics_servlets = {"metrics-servlets", "metrics-servlet"}
reviewed_dual_namespace_artifacts = {
"jackson-core": {
- "jackson-core-2.22.2.jar": "com/fasterxml/jackson/core/",
- "jackson-core-3.2.2.jar": "tools/jackson/core/",
+ "jackson-core-2.22.3.jar": "com/fasterxml/jackson/core/",
+ "jackson-core-3.2.3.jar": "tools/jackson/core/",
},
"jackson-databind": {
- "jackson-databind-2.22.2.jar": "com/fasterxml/jackson/databind/",
- "jackson-databind-3.2.2.jar": "tools/jackson/databind/",
+ "jackson-databind-2.22.3.jar": "com/fasterxml/jackson/databind/",
+ "jackson-databind-3.2.3.jar": "tools/jackson/databind/",
},
}
@@ -132,10 +132,13 @@ def reviewed_dual_namespace_pair(artifact, jars):
required_prefix = expected[jar.name]
with ZipFile(jar) as archive:
classes = {
- entry
+ re.sub(r"^META-INF/versions/(?:9|[1-9][0-9]+)/", "", entry)
for entry in archive.namelist()
if entry.endswith(".class")
}
+ # Multi-release entries are the same loadable class names. Module
+ # descriptors name distinct modules, not duplicate runtime classes.
+ classes.discard("module-info.class")
if not any(entry.startswith(required_prefix) for entry in classes):
return False
forbidden_prefixes = all_prefixes - {required_prefix}
@@ -167,6 +170,14 @@ for lib_dir in lib_dirs:
if artifact:
artifacts[artifact].append(jar)
+ for artifact in sorted(reviewed_dual_namespace_artifacts):
+ jars = artifacts.get(artifact, [])
+ if len(jars) < 2:
+ joined = ",".join(str(jar) for jar in jars)
+ failures.append(
+ f"CATTLE_RUNTIME_JAR_JACKSON_EXPECTED_PAIR lib={lib_dir} artifact={artifact} files={joined}"
+ )
+
for artifact, jars in sorted(artifacts.items()):
if len(jars) > 1:
if reviewed_dual_namespace_pair(artifact, jars):
diff --git a/scripts/check-cattle-runtime-jar-uniqueness-fixtures b/scripts/check-cattle-runtime-jar-uniqueness-fixtures
index bac07335fc..6908245532 100755
--- a/scripts/check-cattle-runtime-jar-uniqueness-fixtures
+++ b/scripts/check-cattle-runtime-jar-uniqueness-fixtures
@@ -42,13 +42,13 @@ for jar in \
metrics-jakarta-servlets-4.2.39.jar; do
touch_jar "$positive_root" "$jar"
done
-namespace_jar "$positive_root" jackson-core-2.22.2.jar \
+namespace_jar "$positive_root" jackson-core-2.22.3.jar \
com/fasterxml/jackson/core/ReviewedJackson2.class
-namespace_jar "$positive_root" jackson-core-3.2.2.jar \
+namespace_jar "$positive_root" jackson-core-3.2.3.jar \
tools/jackson/core/ReviewedJackson3.class
-namespace_jar "$positive_root" jackson-databind-2.22.2.jar \
+namespace_jar "$positive_root" jackson-databind-2.22.3.jar \
com/fasterxml/jackson/databind/ReviewedJackson2.class
-namespace_jar "$positive_root" jackson-databind-3.2.2.jar \
+namespace_jar "$positive_root" jackson-databind-3.2.3.jar \
tools/jackson/databind/ReviewedJackson3.class
positive_output="$workdir/positive.log"
@@ -69,10 +69,14 @@ for expected in \
done
jackson_negative_root="$workdir/jackson-negative"
-namespace_jar "$jackson_negative_root" jackson-core-2.22.2.jar \
+namespace_jar "$jackson_negative_root" jackson-core-2.22.3.jar \
com/fasterxml/jackson/core/ReviewedJackson2.class
-namespace_jar "$jackson_negative_root" jackson-core-3.2.2.jar \
+namespace_jar "$jackson_negative_root" jackson-core-3.2.3.jar \
com/fasterxml/jackson/core/UnexpectedJackson3.class
+namespace_jar "$jackson_negative_root" jackson-databind-2.22.3.jar \
+ com/fasterxml/jackson/databind/ReviewedJackson2.class
+namespace_jar "$jackson_negative_root" jackson-databind-3.2.3.jar \
+ tools/jackson/databind/ReviewedJackson3.class
jackson_negative_output="$workdir/jackson-negative.log"
set +e
RC16_CATTLE_PACKAGED_ROOT="$jackson_negative_root" \
@@ -87,7 +91,7 @@ fi
for expected in \
'CATTLE_RUNTIME_JAR_DUPLICATE_ARTIFACT' \
'artifact=jackson-core' \
- 'reviewed_dual_namespace_count=0' \
+ 'reviewed_dual_namespace_count=1' \
'failure_count=1'; do
if ! grep -F "$expected" "$jackson_negative_output" >/dev/null; then
echo "CATTLE_RUNTIME_JAR_UNIQUENESS_JACKSON_NAMESPACE_MISSING=$expected" >&2
@@ -96,6 +100,46 @@ for expected in \
fi
done
+for missing in jackson-core-2.22.3.jar jackson-core-3.2.3.jar \
+ jackson-databind-2.22.3.jar jackson-databind-3.2.3.jar; do
+ missing_root="$workdir/missing-$missing"
+ for expected_jar in jackson-core-2.22.3.jar jackson-core-3.2.3.jar \
+ jackson-databind-2.22.3.jar jackson-databind-3.2.3.jar; do
+ [ "$expected_jar" != "$missing" ] || continue
+ mkdir -p "$missing_root/app/WEB-INF/lib"
+ cp "$positive_root/app/WEB-INF/lib/$expected_jar" "$missing_root/app/WEB-INF/lib/$expected_jar"
+ done
+ missing_output="$workdir/missing-$missing.log"
+ if RC16_CATTLE_PACKAGED_ROOT="$missing_root" scripts/check-cattle-runtime-jar-uniqueness >"$missing_output" 2>&1; then
+ echo "CATTLE_RUNTIME_JAR_UNIQUENESS_MISSING_GENERATION_DID_NOT_FAIL=$missing" >&2
+ exit 1
+ fi
+ grep -F 'CATTLE_RUNTIME_JAR_JACKSON_EXPECTED_PAIR' "$missing_output" >/dev/null
+ grep -F 'failure_count=1' "$missing_output" >/dev/null
+done
+
+for old_major in 2 3; do
+ old_root="$workdir/old-jackson-$old_major"
+ mkdir -p "$old_root/app/WEB-INF/lib"
+ for expected_jar in jackson-databind-2.22.3.jar jackson-databind-3.2.3.jar; do
+ cp "$positive_root/app/WEB-INF/lib/$expected_jar" "$old_root/app/WEB-INF/lib/$expected_jar"
+ done
+ if [ "$old_major" = 2 ]; then
+ namespace_jar "$old_root" jackson-core-2.22.2.jar com/fasterxml/jackson/core/ReviewedJackson2.class
+ cp "$positive_root/app/WEB-INF/lib/jackson-core-3.2.3.jar" "$old_root/app/WEB-INF/lib/jackson-core-3.2.3.jar"
+ else
+ cp "$positive_root/app/WEB-INF/lib/jackson-core-2.22.3.jar" "$old_root/app/WEB-INF/lib/jackson-core-2.22.3.jar"
+ namespace_jar "$old_root" jackson-core-3.2.2.jar tools/jackson/core/ReviewedJackson3.class
+ fi
+ old_output="$workdir/old-jackson-$old_major.log"
+ if RC16_CATTLE_PACKAGED_ROOT="$old_root" scripts/check-cattle-runtime-jar-uniqueness >"$old_output" 2>&1; then
+ echo "CATTLE_RUNTIME_JAR_UNIQUENESS_OLD_PATCH_DID_NOT_FAIL=$old_major" >&2
+ exit 1
+ fi
+ grep -F 'CATTLE_RUNTIME_JAR_DUPLICATE_ARTIFACT' "$old_output" >/dev/null
+ grep -F 'failure_count=1' "$old_output" >/dev/null
+done
+
negative_root="$workdir/negative"
for jar in \
jakarta.annotation-api-3.0.0.jar \
@@ -108,6 +152,10 @@ for jar in \
metrics-servlets-4.2.39.jar; do
touch_jar "$negative_root" "$jar"
done
+for expected_jar in jackson-core-2.22.3.jar jackson-core-3.2.3.jar \
+ jackson-databind-2.22.3.jar jackson-databind-3.2.3.jar; do
+ cp "$positive_root/app/WEB-INF/lib/$expected_jar" "$negative_root/app/WEB-INF/lib/$expected_jar"
+done
negative_output="$workdir/negative.log"
set +e
diff --git a/scripts/check-pasturestack-source b/scripts/check-pasturestack-source
index 9bc49727b4..bbb8ba4125 100755
--- a/scripts/check-pasturestack-source
+++ b/scripts/check-pasturestack-source
@@ -51,7 +51,7 @@ fi
project_version=$(sed -n 's/^[[:space:]]*\([^<]*\)<\/version>[[:space:]]*$/\1/p' code/meta-parent/pom.xml | head -n 1)
[[ "$project_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail non_numeric_project_version
-require_line code/meta-parent/pom.xml ' 0.183.327'
+require_line code/meta-parent/pom.xml ' 0.183.328'
require_line code/meta-parent/pom.xml ' 2.3.35'
require_line "$iaas_api_defaults" 'auth.service.external.id.types=github_user,github_org,github_team,shibboleth_user,shibboleth_group,ldap_user,ldap_group,oidc_user,oidc_group'
require_line code/meta-parent/pom.xml ' https://github.com/PastureStack/orchestration-engine'
@@ -110,15 +110,15 @@ if grep -Fq 'download.docker.com/linux/static/stable' Dockerfile Dockerfile.dapp
fi
require_line code/packaging/app-config/src/main/resources/META-INF/cattle/api-server/defaults.properties 'supported.docker.range=~v1.12.3 || ~v1.13.0 || ~v17.03.0 || ~v17.06.0 || ~v17.09.0 || ~v17.12.0 || ~v18.03.0 || ~v18.06.0 || ~v18.09.0 || ~v19.03.2 || v24.0.9 || >=v29.4.1 <=v29.7.2 || v29.8.0'
require_line code/packaging/app-config/src/main/resources/META-INF/cattle/api-server/defaults.properties 'newest.docker.version=v29.8.0'
-require_line code/meta-parent/pom.xml ' 2.22.2'
-require_line code/meta-parent/pom.xml ' 5.7.4'
+require_line code/meta-parent/pom.xml ' 2.22.3'
+require_line code/meta-parent/pom.xml ' 5.7.5'
require_line code/meta-parent/pom.xml ' 12.1.12'
require_line code/meta-parent/pom.xml ' 3.21.7'
require_line code/meta-parent/pom.xml ' 3.33.0-GA'
require_line code/meta-parent/pom.xml ' 1.6.3'
require_line code/meta-parent/pom.xml ' 9.0'
require_line code/meta-parent/pom.xml ' 0.31.9.RELEASE'
-require_line code/meta-parent/pom.xml ' 3.2.2'
+require_line code/meta-parent/pom.xml ' 3.2.3'
require_line code/meta-parent/pom.xml ' 42.7.13'
require_line code/meta-parent/pom.xml ' 4.13.2'
require_line tests/integration/requirements.txt 'PyJWT==2.13.0'
@@ -147,15 +147,21 @@ require_line scripts/build ' MAVEN_ARGS="$MAVEN_ARGS" SOURCE_DATE_EPOCH="$SOU
require_line scripts/build ' scripts/install-patched-hazelcast "$maven_cmd"'
require_line scripts/build ' PATH="${JAVA_HOME}/bin:${PATH}"'
require_line scripts/build ' export PATH'
-require_line scripts/install-patched-hazelcast 'runtime_version=5.7.4'
-require_line scripts/install-patched-hazelcast 'release_tag=v5.7.4'
-require_line scripts/install-patched-hazelcast 'release_commit=21fe15f85f0eff12d3ba1f68af3e1753e90ca3bd'
-require_line scripts/install-patched-hazelcast 'release_sha256=6b768e6cff9e5281e77ad14e609b69bac6856ecd4469af827f566be95553644c'
-require_line scripts/install-patched-hazelcast 'jackson3_version=3.2.2'
-require_line scripts/install-patched-hazelcast 'jackson2_version=2.22.2'
+hazelcast_release_commit=$(sed -n 's/^release_commit=//p' scripts/install-patched-hazelcast)
+hazelcast_release_sha256=$(sed -n 's/^release_sha256=//p' scripts/install-patched-hazelcast)
+hazelcast_release_asset_id=$(sed -n 's/^release_asset_id=//p' scripts/install-patched-hazelcast)
+[[ "$hazelcast_release_commit" =~ ^[0-9a-f]{40}$ && "$hazelcast_release_sha256" =~ ^[0-9a-f]{64}$ && "$hazelcast_release_asset_id" =~ ^[1-9][0-9]*$ ]] || fail hazelcast_release_identity_pending
+require_line scripts/install-patched-hazelcast 'runtime_version=5.7.5'
+require_line scripts/install-patched-hazelcast 'release_tag=v5.7.5'
+require_line scripts/install-patched-hazelcast 'release_commit=a9aea563870201462dc24f778a06279a08ed5841'
+require_line scripts/install-patched-hazelcast 'release_sha256=0f536a9c7bcd00f2369586fb6ca1606f7e45f3225e24795d10d38397051c8715'
+require_line scripts/install-patched-hazelcast 'release_asset_id=602470126'
+require_line scripts/install-patched-hazelcast 'jackson3_version=3.2.3'
+require_line scripts/install-patched-hazelcast 'jackson2_version=2.22.3'
+require_text scripts/install-patched-hazelcast 'PATCHED_HAZELCAST_RELEASE_IDENTITY_PENDING: no download or install performed'
require_line scripts/install-patched-hazelcast 'release_url="https://github.com/PastureStack/distributed-cache-runtime/releases/download/${release_tag}/hazelcast-${runtime_version}.jar"'
require_line scripts/install-patched-hazelcast 'if ! curl --proto '\''=https'\'' --tlsv1.2 --fail --silent --show-error --location \'
-require_line scripts/install-patched-hazelcast 'release_asset_api="https://api.github.com/repos/PastureStack/distributed-cache-runtime/releases/assets/552255174"'
+require_line scripts/install-patched-hazelcast 'release_asset_api="https://api.github.com/repos/PastureStack/distributed-cache-runtime/releases/assets/${release_asset_id}"'
require_line scripts/install-patched-hazelcast ' --header '\''Accept: application/octet-stream'\'' \'
require_line scripts/install-patched-hazelcast 'printf '\''%s %s\n'\'' "$release_sha256" "$runtime_jar" | sha256sum -c -'
require_line scripts/install-patched-hazelcast '"$maven_cmd" ${MAVEN_ARGS:-} org.apache.maven.plugins:maven-install-plugin:3.1.4:install-file \'
@@ -410,4 +416,4 @@ require_line README.md 'modernize the Rancher 1.6 ecosystem. It is not affiliate
require_line README.md 'by Rancher Labs or SUSE.'
require_line ORIGIN.md '- Preserved upstream boundary: `82d154a53f4089fecfb9f320caad826bb4f6055f`'
-printf 'PASTURESTACK_SOURCE_GATE_OK version=0.183.327 runtime_sources=github_release images=digest_pinned ubuntu=26.04 ubuntu_snapshot=20260826T000000Z jdk=25.0.4 maven=3.9.16 patched_hazelcast=5.7.4 docker_cli=29.7.2 docker_host_29_8_0=exact credential_secret_capacity=mediumtext port_preflight=authoritative volume_preflight=runtime_resolution_aligned volume_preflight_project_schema=authorized volume_preflight_type_set=registered v1_hardware_schema=container-and-launchConfig network_driver_rollback=launch-config-restored stack_driver_rollback=child-launch-config-restored auth_token_session_binding=authorized-create-only auth_token_transport=bare-or-bearer-normalized auth_token_frozen_v1_schema=base-superadmin-token oidc_external_types=validated-before-mutation-owned-stable-account oidc_account_activation=sync-before-mfa oidc_v1_project_member_schema=core-options-merged-scoped oidc_identity_link_owner=explicit-and-verified legacy_token_link_repair=exact-match-only oidc_required_local_recovery=active-admin-only default_project=shared-idempotent-role-preserving,atomic-identity-set oidc_restricted_project_membership=stable-account-aware-required-allowlist-only mfa_policy_confirmation=actor-purpose-digest-single-use auth_config_proxy_identity=caller-platform-credential project_member_collection_acl=requested-project-checked-before-load project_template_v1_public=readonly-frozen-field-merged network_purge=retry-removing dev_artifact=forbidden\n'
+printf 'PASTURESTACK_SOURCE_GATE_OK version=0.183.328 runtime_sources=github_release images=digest_pinned ubuntu=26.04 ubuntu_snapshot=20260826T000000Z jdk=25.0.4 maven=3.9.16 patched_hazelcast=5.7.5 docker_cli=29.7.2 docker_host_29_8_0=exact credential_secret_capacity=mediumtext port_preflight=authoritative volume_preflight=runtime_resolution_aligned volume_preflight_project_schema=authorized volume_preflight_type_set=registered v1_hardware_schema=container-and-launchConfig network_driver_rollback=launch-config-restored stack_driver_rollback=child-launch-config-restored auth_token_session_binding=authorized-create-only auth_token_transport=bare-or-bearer-normalized auth_token_frozen_v1_schema=base-superadmin-token oidc_external_types=validated-before-mutation-owned-stable-account oidc_account_activation=sync-before-mfa oidc_v1_project_member_schema=core-options-merged-scoped oidc_identity_link_owner=explicit-and-verified legacy_token_link_repair=exact-match-only oidc_required_local_recovery=active-admin-only default_project=shared-idempotent-role-preserving,atomic-identity-set oidc_restricted_project_membership=stable-account-aware-required-allowlist-only mfa_policy_confirmation=actor-purpose-digest-single-use auth_config_proxy_identity=caller-platform-credential project_member_collection_acl=requested-project-checked-before-load project_template_v1_public=readonly-frozen-field-merged network_purge=retry-removing dev_artifact=forbidden\n'
diff --git a/scripts/check-release-artifact b/scripts/check-release-artifact
index 69851a94c3..05de760b45 100755
--- a/scripts/check-release-artifact
+++ b/scripts/check-release-artifact
@@ -4,7 +4,7 @@ set -euo pipefail
cd "$(dirname "$0")/.."
artifact=${1:-dist/artifacts/cattle.jar}
-expected_version=${EXPECTED_ENGINE_VERSION:-0.183.327}
+expected_version=${EXPECTED_ENGINE_VERSION:-0.183.328}
test -f "$artifact"
artifact=$(realpath "$artifact")
diff --git a/scripts/ci b/scripts/ci
index a3ddd70a3f..3902a5f41f 100755
--- a/scripts/ci
+++ b/scripts/ci
@@ -43,6 +43,7 @@ ensure_docker()
ensure_docker
+python3 ./test-jackson-security-floors.py -v
./check-cattle-dependency-hygiene
./check-cattle-archaius-boundary
./check-cattle-jmx-boundary
diff --git a/scripts/install-patched-hazelcast b/scripts/install-patched-hazelcast
index 44bb15bba8..620ddab2ff 100755
--- a/scripts/install-patched-hazelcast
+++ b/scripts/install-patched-hazelcast
@@ -5,16 +5,22 @@ repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
cd "$repo_root"
maven_cmd=${1:-mvn}
-runtime_version=5.7.4
-release_tag=v5.7.4
-release_commit=21fe15f85f0eff12d3ba1f68af3e1753e90ca3bd
-release_sha256=6b768e6cff9e5281e77ad14e609b69bac6856ecd4469af827f566be95553644c
-jackson3_version=3.2.2
-jackson2_version=2.22.2
+runtime_version=5.7.5
+release_tag=v5.7.5
+# Official 5.7.5 release identities verified by published-asset readback.
+release_commit=a9aea563870201462dc24f778a06279a08ed5841
+release_sha256=0f536a9c7bcd00f2369586fb6ca1606f7e45f3225e24795d10d38397051c8715
+release_asset_id=602470126
+jackson3_version=3.2.3
+jackson2_version=2.22.3
+if ! [[ "$release_commit" =~ ^[0-9a-f]{40}$ && "$release_sha256" =~ ^[0-9a-f]{64}$ && "$release_asset_id" =~ ^[1-9][0-9]*$ ]]; then
+ echo 'PATCHED_HAZELCAST_RELEASE_IDENTITY_PENDING: no download or install performed' >&2
+ exit 1
+fi
release_url="https://github.com/PastureStack/distributed-cache-runtime/releases/download/${release_tag}/hazelcast-${runtime_version}.jar"
# Same immutable release asset, for GitHub release-URL gateway outages.
# Both download paths must pass the identical byte hash and metadata checks.
-release_asset_api="https://api.github.com/repos/PastureStack/distributed-cache-runtime/releases/assets/552255174"
+release_asset_api="https://api.github.com/repos/PastureStack/distributed-cache-runtime/releases/assets/${release_asset_id}"
work_root="$repo_root/target/third-party/hazelcast-${runtime_version}"
case "$work_root" in
diff --git a/scripts/test-jackson-security-floors.py b/scripts/test-jackson-security-floors.py
new file mode 100644
index 0000000000..a28326d3af
--- /dev/null
+++ b/scripts/test-jackson-security-floors.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python3
+"""Exercise the real POM/JAR Jackson floor blocks without Maven or network."""
+import ast
+import io
+import re
+import subprocess
+import sys
+import tempfile
+import unittest
+import zipfile
+from pathlib import Path
+
+
+REPO = Path(__file__).resolve().parent.parent
+SOURCE = (REPO / "scripts/check-cattle-dependency-hygiene").read_text(encoding="utf-8")
+BLOCKS = dict(re.findall(
+ r"(?ms)^(jackson_security_floor_\w+)=\$\(\n\s*python3 - <<'PY'\n(.*?)\nPY\n\)", SOURCE))
+POM = (REPO / "code/meta-parent/pom.xml").read_text(encoding="utf-8")
+
+
+def findings(kind, root):
+ result = subprocess.run([sys.executable, "-c", BLOCKS[kind]], cwd=root,
+ capture_output=True, text=True, check=True)
+ return result.stdout.strip()
+
+
+class JacksonSecurityFloorsTest(unittest.TestCase):
+ def test_multi_release_namespaces_reject_foreign_classes_but_allow_module_descriptors(self):
+ source = (REPO / "scripts/check-cattle-runtime-jar-uniqueness").read_text(encoding="utf-8")
+ program = ast.parse(source.split("<<'PY'\n", 1)[1].rsplit("\nPY", 1)[0])
+ nodes = [node for node in program.body
+ if isinstance(node, (ast.Import, ast.ImportFrom, ast.FunctionDef))
+ or isinstance(node, ast.Assign) and any(
+ isinstance(name, ast.Name) and name.id == "reviewed_dual_namespace_artifacts"
+ for name in node.targets)]
+ namespace = {}
+ exec(compile(ast.Module(body=nodes, type_ignores=[]), "", "exec"), namespace)
+ payloads = {}
+
+ def jar(name, entries):
+ output = io.BytesIO()
+ with zipfile.ZipFile(output, "w") as archive:
+ for entry in entries:
+ archive.writestr(entry, b"fixture")
+ payloads[name] = output.getvalue()
+ return Path(name)
+
+ namespace["ZipFile"] = lambda path: zipfile.ZipFile(io.BytesIO(payloads[path.name]))
+ check = namespace["reviewed_dual_namespace_pair"]
+ for artifact in ("jackson-core", "jackson-databind"):
+ suffix = "core" if artifact == "jackson-core" else "databind"
+ for major, version, prefix in ((2, "2.22.3", "com/fasterxml"), (3, "3.2.3", "tools")):
+ with self.subTest(artifact=artifact, major=major):
+ own = f"{prefix}/jackson/{suffix}/Reviewed.class"
+ other_prefix = "tools" if major == 2 else "com/fasterxml"
+ other = f"{other_prefix}/jackson/{suffix}/Reviewed.class"
+ other_version = "3.2.3" if major == 2 else "2.22.3"
+ first = jar(f"{artifact}-{version}.jar", [own, f"META-INF/versions/25/{own}",
+ "module-info.class"])
+ second = jar(f"{artifact}-{other_version}.jar", [other,
+ "META-INF/versions/9/module-info.class"])
+ self.assertTrue(check(artifact, [first, second]))
+ for foreign in (other, f"META-INF/versions/9/{other}", f"META-INF/versions/25/{other}"):
+ jar(first.name, [own, foreign, "module-info.class"])
+ self.assertFalse(check(artifact, [first, second]), foreign)
+
+ def check_pom(self, text):
+ with tempfile.TemporaryDirectory(prefix="engine328-jackson-pom-") as directory:
+ root = Path(directory)
+ pom = root / "code/meta-parent/pom.xml"
+ pom.parent.mkdir(parents=True)
+ pom.write_text(text, encoding="utf-8")
+ return findings("jackson_security_floor_dependencies", root)
+
+ def check_jars(self, names):
+ with tempfile.TemporaryDirectory(prefix="engine328-jackson-jars-") as directory:
+ root = Path(directory)
+ lib = root / "code/packaging/app/target/app/WEB-INF/lib"
+ lib.mkdir(parents=True)
+ for name in names:
+ (lib / name).touch()
+ return findings("jackson_security_floor_jars", root)
+
+ def test_pom_patched_lines_accept_and_older_or_qualified_versions_reject(self):
+ self.assertEqual(set(BLOCKS), {
+ "jackson_security_floor_dependencies", "jackson_security_floor_jars"})
+ self.assertEqual(self.check_pom(POM), "")
+ for name, current, rejected in [
+ ("jackson.version", "2.22.3", "2.22.2"),
+ ("webauthn.jackson.version", "3.2.3", "3.2.2"),
+ ("jackson.version", "2.22.3", "2.22.3-SNAPSHOT"),
+ ("webauthn.jackson.version", "3.2.3", "3.2.3-RC1")]:
+ with self.subTest(property=name, rejected=rejected):
+ before = f"<{name}>{current}{name}>"
+ self.assertIn(before, POM)
+ self.assertTrue(self.check_pom(POM.replace(before, f"<{name}>{rejected}{name}>")))
+
+ def test_packaged_patched_lines_and_patchless_annotations_accept(self):
+ self.assertEqual(self.check_jars([
+ "jackson-core-2.22.3.jar", "jackson-databind-2.22.3.jar",
+ "jackson-core-3.2.3.jar", "jackson-databind-3.2.3.jar",
+ "jackson-dataformat-cbor-3.2.3.jar", "jackson-annotations-2.22.jar"]), "")
+
+ def test_packaged_old_lines_qualifiers_and_patched_annotations_reject(self):
+ for name in ["jackson-core-2.22.2.jar", "jackson-databind-2.22.2.jar",
+ "jackson-core-3.2.2.jar", "jackson-databind-3.2.2.jar",
+ "jackson-databind-2.22.3-SNAPSHOT.jar", "jackson-annotations-2.22.3.jar"]:
+ with self.subTest(jar=name):
+ self.assertTrue(self.check_jars([name]))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/third-party/HAZELCAST.md b/third-party/HAZELCAST.md
index 77c124cd70..1ac017a043 100644
--- a/third-party/HAZELCAST.md
+++ b/third-party/HAZELCAST.md
@@ -2,7 +2,7 @@
The orchestration engine embeds the reviewed runtime produced by the dedicated `distributed-cache-runtime` repository. It does not rebuild a second, diverging Hazelcast fork during every orchestration build.
-## Provenance
+## Published 5.7.4 provenance (historical)
- Source project: [`PastureStack/distributed-cache-runtime`](https://github.com/PastureStack/distributed-cache-runtime)
- Annotated release tag: `v5.7.4`
@@ -15,6 +15,32 @@ The source project owns the Java 25 build, focused legitimate and malicious regr
This removes the former duplicate source-download, patch, and rebuild path. Dependency changes are reviewed and tested once in the source project; orchestration consumes only the corresponding pinned release bytes.
+## Published 5.7.5 provenance for the unbuilt Engine328 candidate
+
+- Official numeric release: [`v5.7.5`](https://github.com/PastureStack/distributed-cache-runtime/releases/tag/v5.7.5), release ID `400661425`, public and non-draft
+- Verified signed tag object: `818592fbf7dd0506862216211edc99b3e009a414`
+- Tag target / artifact source commit: `a9aea563870201462dc24f778a06279a08ed5841`
+- Runtime artifact: `hazelcast-5.7.5.jar`
+- GitHub asset ID: `602470126`
+- Actual downloaded size: `23,852,246` bytes
+- Actual downloaded SHA-256: `0f536a9c7bcd00f2369586fb6ca1606f7e45f3225e24795d10d38397051c8715`
+- Embedded Jackson 3 / Jackson 2: `3.2.3` / `2.22.3`
+
+Published-asset readback matched the source, tag, and JAR identities above.
+The source-identical producer merge is
+`a8416bd1b96bb08250095441e9816c8116d31aec`, with tree
+`1ebcb081cc575a6e785af2c37e9af3b61df03022`.
+[Producer build/security run `36815272664`](https://github.com/PastureStack/distributed-cache-runtime/actions/runs/36815272664)
+passed 40 suites / 510 tests with zero failures, errors, or skips.
+[Producer CodeQL run `36815270196`](https://github.com/PastureStack/distributed-cache-runtime/actions/runs/36815270196)
+passed with the exact Java SARIF showing 120 rules, zero results,
+zero severity-at-least-7 findings, and zero unresolved rule metadata.
+
+The Engine installer and source oracle now pin these exact official identities;
+the old 5.7.4 hash is not reused. Engine328 has not yet been built or published.
+Its Java regression cases and full artifact/SBOM/runtime gates remain pending;
+the producer's results do not stand in for those consumer checks.
+
## License
Hazelcast remains third-party software licensed by its upstream authors under Apache License 2.0. The original license and notice materials are preserved in the release artifact and in the Server runtime license bundle. PastureStack claims authorship only for its compatibility and security changes.