Dependency Upgrade Plan
Major-version upgrades and unmaintained libraries that are deliberately not done as routine
Dependabot bumps. Each needs its own PR because it changes APIs that TrustWeave code, tests or
consumers compile against. Minor and patch updates within the current major still go through
Dependabot and gradle/libs.versions.toml as usual.
Status as of 3 October 2026. Versions are the catalog versions on main; “latest” is the newest
release on Maven Central when this was written. Update this page in the same PR that completes an item.
| Item | Current | Target | Scope | Risk | Owner |
|---|---|---|---|---|---|
| Unmaintained Vault driver | com.bettercloud:vault-java-driver 5.1.0 |
Maintained client or plain HTTP | kms:plugins:hashicorp |
Medium | TBD (assign) |
| DIDComm library with embedded Nimbus | org.didcommx:didcomm 0.3.2 |
Maintained implementation | credentials:plugins:didcomm |
High (security) | TBD (assign) |
| Ktor 3 | 2.3.13 | 3.x (latest 3.6.0) | ~14 build files (servers, clients) | High | TBD (assign) |
| OkHttp 5 | 4.12.0 | 5.x (latest 5.5.0) | 36 build files | Medium | TBD (assign) |
| Kotest 6 | 5.9.1 | 6.x (latest 6.2.5) | 2 build files, 6 test sources | Low | TBD (assign) |
| Testcontainers 2 | 1.21.4 | 2.x (latest 2.0.5) | 10 build files | Medium | TBD (assign) |
| kotlinx-datetime 0.7+ | 0.6.2 | 0.7.x / 0.8.x | 58 build files, ~230 sources; public API | High | TBD (assign) |
| bitcoinj 0.17 | 0.16.2 (bitcoinj-legacy) |
0.17.x | 2 build files | Medium | TBD (assign) |
Routine bumps done in the current cycle
Within-major updates that were safe to take without a migration, verified by compiling and testing the modules that use them: Jackson 2.22.3, Bouncy Castle 1.86 (both clear advisories that OSV reported against the previous versions), SLF4J 2.0.20, MongoDB BSON 4.11.5, Azure Identity 1.18.7. Still open and routine (Dependabot can propose them): Hikari 7.1.0, web3j 5.0.3, OpenTelemetry 1.66.0, json-path 2.10.0, Kover 0.9.11, AWS SDK BOM 2.55.x, Google libraries-bom 26.90.0, Azure SDK BOM 1.3.8. Take them in separate small PRs and run the affected modules’ tests.
The remaining OSV advisories are tracked in config/osv/baseline.json (see SECURITY.md). Most come
from transitive Netty 4.1.x, Jackson 2.17/2.18 and Bouncy Castle 1.69-1.80 copies pulled in by cloud
SDKs and web3j; upgrading those SDK BOMs is the way to shrink the baseline. After each upgrade,
regenerate the report and remove the entries that no longer appear.
vault-java-driver
com.bettercloud:vault-java-driver has had no release since 2019 and its repository is archived.
It is only used by kms:plugins:hashicorp (4 source files) to call Vault’s Transit engine.
Risk: unpatched TLS/HTTP handling in an unmaintained client that carries key-management traffic.
Steps:
- Inventory the Vault calls the plugin makes (Transit
keys,sign,verify, auth login). - Choose a replacement: the community fork
io.github.jopenlibs:vault-java-driver(drop-in, package renamecom.bettercloud.vault→io.github.jopenlibs.vault) is the smallest change; a thin client over the HTTP API with OkHttp/Ktor removes the dependency entirely. - Swap the catalog alias, update imports, and run the plugin’s tests plus the Vault Testcontainers suite.
- Note the change in
CHANGELOG.md; the plugin’s public API does not change.
Recommended approach (documentation only, no code change yet): replace the driver with a thin
internal client over Vault’s HTTP API using the OkHttp the project already depends on. The plugin
needs only POST /v1/auth/<method>/login (static token needs no call; AppRole login is the only auth call the plugin makes today), POST/GET
/v1/transit/keys/<name>, POST /v1/transit/sign/<name> and POST /v1/transit/verify/<name>, with
the X-Vault-Token header. That is a few hundred lines, removes the
unmaintained dependency and its TLS code, and lets the plugin reuse the repository’s SSRF and timeout
conventions. The jopenlibs fork is the fallback if a drop-in is needed in a hurry. Keep the existing
parsing of Vault public keys (strict, curve-checked) and the Testcontainers Vault suite as the
regression gate.
Next step: open an issue for the plugin owner (TBD), write the HTTP client behind the existing plugin interface, run the Vault suite against the old and new clients, then remove the catalog alias.
didcommx
org.didcommx:didcomm 0.3.2 (August 2022, still the latest release) embeds Nimbus JOSE+JWT
9.16-preview.1 and json-smart 2.4.7, which carry denial-of-service advisories. See
SECURITY.md, Known Dependency Risks
for the advisories and the mitigations required of users in the meantime.
Steps:
- Checked on 3 October 2026: Maven Central has no didcomm release after 0.3.2, so there is nothing
to bump. The OSV gate (
config/osv/baseline.json) now fails on any new advisory against the embedded copies. - Check for a didcommx release that depends on (rather than shades) a current Nimbus (recheck quarterly).
- Otherwise evaluate a maintained DIDComm v2 implementation, or implement packing/unpacking on
the catalog’s Nimbus (9.48+) behind the existing
crypto/interopadapter boundary. - Remove the
nimbus-jose-jwtexclusion fromcredentials/plugins/didcomm/build.gradle.ktsonce no shaded copy remains, and drop the SECURITY.md entry when the OSV-Scanner job (.github/workflows/security.yml) no longer reports the embedded copies.
Ktor 3
Used by the registrar, VC API, OIDC4VCI, status-list and trust-registry servers (libs.bundles.ktor-server)
and by HTTP clients (libs.bundles.ktor-client).
Risk: Ktor 3 moves to kotlinx-io, changes ApplicationEngine/EmbeddedServer startup, removes
deprecated APIs and changes some plugin configuration DSLs; server tests (ktor-server-test-host)
need testApplication updates. Servers are published artifacts, so behaviour must be re-qualified
(the host observability and conformance workflows).
Steps:
- Bump
ktorin the catalog on a branch and compile everything that uses it (grep -rl "libs.ktor\|libs.bundles.ktor" --include=build.gradle.kts). - Fix server bootstrap (
embeddedServer(...).start(wait = ...)),call.receive/respondchannel APIs and anyByteReadChannelcode for kotlinx-io. - Run each server’s tests and
./gradlew checkKotlinAbi; update ABI dumps where server APIs legitimately change and record it inCHANGELOG.md. - Re-run conformance (
conformance-pr.yml) and host observability checks fromci.yml.
OkHttp 5
Used in 36 modules, mostly as an HTTP client for DID methods, anchors and KMS providers;
mockwebserver is used in tests.
Risk: OkHttp 5 is source-compatible for most client code, but mockwebserver moves to
mockwebserver3 with a new API, and the artifact is published as Kotlin Multiplatform (okhttp-jvm
resolution through Gradle metadata). Interceptors and TLS configuration must be re-checked.
Steps:
- Bump
okhttp; switch test code fromokhttp3.mockwebservertomockwebserver3(com.squareup.okhttp3:mockwebserver3) and update its catalog alias. - Compile and run tests for all 36 modules (in batches; see CLAUDE.md for targeted Gradle tasks).
- Check the CycloneDX SBOM for a single OkHttp/Okio version afterwards.
Kotest 6
Only assertions/runner in 2 build files and 6 test sources.
Risk: low; Kotest 6 needs Kotlin 2.2+ (satisfied) and renames some matchers/packages.
Steps: bump kotest, fix imports in the 6 test files, run those modules’ tests.
Testcontainers 2
Used by 10 modules’ tests (PostgreSQL, Vault, LocalStack-style integration tests).
Risk: Testcontainers 2 drops JUnit 4, renames the module artifacts to testcontainers-<module>
(for example org.testcontainers:testcontainers-postgresql) and moves container classes to
per-module packages. CI relies on these suites for qualification evidence.
Steps:
- Update the catalog coordinates (
testcontainers,testcontainers-junit,testcontainers-postgresql) to the 2.x artifact names. - Update imports and any
@Container/@Testcontainersusage; remove JUnit 4 rule usage. - Run the Docker-backed suites in CI (they cannot run where Docker is unavailable).
kotlinx-datetime
kotlinx.datetime.Instant/Clock appear in about 230 source files across 58 modules,
including public API (credential and DID document models).
Risk: high. kotlinx-datetime 0.7 removes kotlinx.datetime.Instant and Clock in favour of
Kotlin’s kotlin.time.Instant/kotlin.time.Clock (stable in Kotlin 2.3). Every public signature
that exposes kotlinx.datetime.Instant changes, which is a binary-incompatible change for
consumers and for serialized formats that rely on its serializer.
Steps:
- Decide the public API type (
kotlin.time.Instantis the forward path) and announce the break inCHANGELOG.mdfor the next minor release. - Optionally stage it: move to the
0.7.x-0.6.x-compat/0.8.0-0.6.x-compatartifact first, which keeps the old classes while the code migrates. - Migrate module by module, regenerate ABI dumps (
./gradlew updateKotlinAbi) and review the diffs, and verify JSON serialization of timestamps is unchanged (ISO-8601) with the existing round-trip tests.
bitcoinj
Already recorded in gradle/libs.versions.toml: two consumers still build against 0.16.2 through
the bitcoinj-legacy alias because 0.17 moves Transaction, NetworkParameters, HEX and
isOpReturn. Migrate those two modules, then delete the legacy alias.