Product documentation
Pre-production security posture + dependency audit
A pre-production security pass over oathy: pinned-dependency CVE review and the security-relevant deployment/config invariants, with an honest OK / GAP / UNKNOWN verdict per area and links to the tracking tickets.
Pre-production security posture + dependency audit
This is the pre-production security pass called for as oathy approaches its production cutover. It covers two things: a CVE review of the pinned dependency versions, and the security-relevant deployment and configuration invariants the platform will ship with.
It is a findings report, not a set of fixes — every genuine gap is tracked by a linked ticket rather than patched here, because a security change deserves its own reviewed PR.
Validation boundary
Read this as a static review — source, chart, workflow, and Git branch-protection inspection, plus a live CVE lookup against public advisory databases as of the audit date. It is not a penetration test and not a running-system scan. In particular:
- Dependency CVE claims name the CVE, the affected range, and the pinned version. They are grounded in public advisories retrieved on the audit date. The assistant's own training cut-off is January 2026, so the 2026 advisory detail here comes from live lookups; anything disclosed after the audit date is unknown and needs a fresh scan.
- Resolved transitive versions (for example, the exact Spring Security version Spring Boot
pulls) were read from the managed BOM and the project's own documentation, not from a live
mvn dependency:tree. Confirm them with a real resolve before acting. - Branch-protection state was read from the GitHub API on the audit date; it is a mutable setting, so re-check it at cutover.
- Nothing here observes the live cluster. Runtime posture (actual ingress TLS, actual NetworkPolicy enforcement by the cluster CNI, actuator reachability from the public internet) needs a live probe or a pentest to confirm.
Verdict
Prod-security-readiness: conditional-pass, with governance and config gaps to close first.
The dependency posture is genuinely strong. Every pin reviewed sits at or above the fix
line for the 2026 CVE waves — Spring Boot 4.0.6 is one patch above the range CVE-2026-40976
(critical) hits, Jackson 2.22.1 is a fixed version for the June-2026 Jackson RCE batch, and
Bouncy Castle 1.85 clears its known advisories. No unpatched known-critical dependency was
found at the pinned versions as of the audit date. That is a clean result stated with evidence,
not an absence of looking.
A subsequent live resolve (SSO-2224) went beyond the explicit pins to the full
Boot-managed transitive closure — the "confirm with a real resolve" caveat above — and did
surface a Critical/High backlog there that the pin review did not cover: tomcat-embed, the
postgresql JDBC driver, and ONGRES scram (all now remediated in bom/pom.xml), plus a
Bouncy Castle version skew — bcpkix/bcutil-jdk18on arriving transitively at 1.77 beside
the pinned bcprov 1.85, now all pinned to 1.85. After these, a fresh full-reactor
mvn dependency:tree cross-checked against the OSV.dev API shows the only remaining
Critical/High is a test-scope-only protobuf-java (CVE-2024-7254), tracked under
SSO-2225; the rest of the residual is MODERATE/LOW — now also cleared, with SSO-2239
pinning OpenTelemetry to 1.62.0 and Logback to 1.5.34 (see Part A).
The material items are governance and configuration, not vulnerable code:
- Spring Security
7.0.5(via Spring Boot4.0.6) is fixed for the critical Dynamic Client Registration CVE, but trails the June-20267.0.6batch that patched a SAML-processing CVE — and the platform ships a SAML federation member (SSO-2160). - Several security-relevant CI guards run on every PR but are not in branch-protection's required checks, so they do not actually block a merge — including the SSRF guard (SSO-2162).
- CVE scanning was advisory-only — nothing blocked a PR on a vulnerable dependency
(SSO-1620 / SSO-742). Since this audit, SSO-742 wired both scanners into
real gates that run per-PR and fail visibly (OWASP DC
failBuildOnCVSS=7; osv-scanner fails on Critical/High — its invocation was also silently broken, see below). They are deliberately kept non-required in branch protection until a known transitive-HIGH backlog is remediated (SSO-2195), so they surface the gap without blocking merges.
None of these is a shipped exploit path today; all three should be closed before the prod cutover. The CI security guards that are required (29 contexts) cover the highest-value token, crypto, cookie, host-header, and Kubernetes-hardening invariants — see CI security guards.
Findings summary
Severity is the assistant's assessment for the pre-prod context; re-rate where a ticket calls for triage. Status is OK (invariant holds, evidenced), GAP (a real shortfall), or UNKNOWN (needs a live scan or pentest to settle).
Part A — dependencies / CVEs
| Area | Severity | Status | Evidence | Ticket |
|---|---|---|---|---|
| Jackson 2.x default-typing posture | — | OK | jackson.version = 2.22.1, a fixed version for the June-2026 Jackson batch (CVE-2026-54513 RCE, CVE-2026-54512 CVSS 9.2); check-no-default-typing is a required gate. | — |
| Jackson pin comment drift | Low | GAP | bom/pom.xml comment + CLAUDE.md still describe a 2.21.3 pin, which is below the 2.21.4 fix line — a reversion trap. | SSO-2161 (new) |
Spring Boot 4.0.6 | — | OK | CVE-2026-40976 (critical, auth bypass) affects 4.0.0 through 4.0.5; 4.0.6 is the fix. | — |
| Spring Security 7.0.x (DCR CVE) | — | OK | CVE-2026-22752 (CVSS 9.6, Authorization Server DCR) is fixed in 7.0.5, which Boot 4.0.6 pulls; the hub does enable DCR. | — |
Spring Security 7.0.5 trails 7.0.6 | Medium | GAP | 7.0.6 (2026-06-09) fixed 7 further CVEs incl. SAML processing; saml-member uses spring-security-saml2-service-provider. | SSO-2160 (new) |
Bouncy Castle — bcprov 1.85, but bcpkix/bcutil skewed to 1.77 | Medium | REMEDIATED | The bom pinned only bcprov-jdk18on → 1.85; bcpkix/bcutil-jdk18on leaked in transitively at 1.77 (saml-member: opensaml → cryptacular) — a BC version skew carrying CVE-2025-8916 + CVE-2026-5588 (both MODERATE). SSO-2224 pins all three to 1.85, clearing both. bcprov 1.85 already cleared CVE-2025-8885 (≤ 1.77) + CVE-2026-0636 (1.74–1.83). | SSO-2224 |
Nimbus JOSE+JWT 10.9.1 | — | OK | CVE-2024-21235 algorithm-confusion is structurally mitigated by the required jwt-decoder-algorithm-check (ES256 allow-list). | — |
| CVE scan as a merge gate | Medium | GAP (partially closed) | Was: OWASP DC weekly/push failBuildOnCVSS=11 (never fails), no NVD_API_KEY; osv-scanner weekly, issue-only. SSO-742 since wired both as real per-PR gates (DC failBuildOnCVSS=7; osv fail-on-Critical/High) and fixed osv-scanner's silently-broken v1 invocation. Kept non-required pending transitive-HIGH remediation. | SSO-1620 / SSO-742 (done) → SSO-2195 (remediate + promote to required) |
| Boot-managed / transitive CVEs (live resolve) | High | REMEDIATED | A live mvn dependency:tree + osv-scanner v2.3.8 resolve (the caveat in the Validation boundary) surfaced Critical/High advisories in Boot-4.0.6-managed / transitive artifacts the explicit-pin review did not reach: tomcat-embed 11.0.21 (3 CRITICAL + 3 HIGH, CVE-2026-43515 / -43512 / -41293 / -42498 / -43513 / -41284), postgresql JDBC 42.7.10 (2 HIGH, CVE-2026-54291 / -42198), ONGRES scram 3.2 (1 HIGH, CVE-2026-53712). Pinned in bom/pom.xml → 11.0.24 / 42.7.13 / 3.4. A follow-up resolve also caught a Bouncy Castle skew (bcpkix/bcutil-jdk18on 1.77 beside bcprov 1.85), now pinned to 1.85 (see the Bouncy Castle row). After these, a fresh full-reactor resolve shows no remaining Critical/High except test-scope protobuf-java 4.26.1 (via grpc, CVE-2024-7254, HIGH) — tracked under SSO-2225; residual MODERATE/LOW (opentelemetry 1.55.0, logback 1.5.32) since remediated under SSO-2239 (see the OpenTelemetry + Logback row). | SSO-2224, SSO-2225, SSO-2239 |
| OpenTelemetry + Logback residual (MODERATE/LOW) | Moderate / Low | REMEDIATED | The residual below the Critical/High bar the SSO-2224 resolve left: io.opentelemetry:* 1.55.0 (MODERATE, CVE-2026-45292 / GHSA-rcgg-9c38-7xpx — unbounded W3C-baggage-propagation memory + CPU allocation, fixed 1.62.0) and logback-classic/logback-core 1.5.32 (LOW — CVE-2026-10532 fixed 1.5.34, CVE-2026-9828 fixed 1.5.33; HardenedObjectInputStream object-injection, only when the hardened receiver is explicitly enabled). SSO-2239 pins the otel family via an opentelemetry-bom 1.62.0 import and logback via explicit logback-classic/-core 1.5.34 dependencyManagement entries, both before the spring-boot-dependencies import; a fresh full-reactor dependency:tree confirms otel 1.62.0 + logback 1.5.34 with no other managed version regressed. | SSO-2239 |
| Dependabot coverage | — | OK | .github/dependabot.yml covers Maven + GitHub Actions weekly, grouped Spring/Kotlin/shared-libs, labelled security. | — |
| Remaining pinned libraries | — | UNKNOWN | okhttp 5.4.0, pdfbox 3.0.8, bucket4j 8.10.1, twilio 12.1.1, tink 1.23.0, geoip2 5.2.0, pact 4.7.3 (test): no known high/critical at the pinned versions as of the audit date, but all post-date the training cut-off — confirm with a live scan. | — |
Part B — security posture (config / invariants)
| Area | Severity | Status | Evidence | Ticket |
|---|---|---|---|---|
| Ingress TLS | — | OK | ingress-tls-annotations-check is a required gate; SSL-bundle references use the #{null} SpEL default across hub / product-api / api-gateway / synthetic-monitor. | — |
| Staging TLS cert | High | GAP | Staging hub wildcard cert expired (cert-manager ACME challenge stuck). | SSO-2119 (tracked) |
| Default-deny NetworkPolicy (ingress) | — | OK | Namespace-wide default-deny-ingress renders and is enabled in values-staging.yaml (networkPolicy.enabled: true). | — |
| Default-deny NetworkPolicy (egress) | Medium | GAP | networkPolicy.egressEnabled: false in staging and enabled: false by default in values.yaml; no prod values file yet. Hub keeps its own per-service egress policy as SSRF defence-in-depth. | SSO-1797 (tracked) |
| Operator-set / seed secrets | — | OK (tracked follow-ups) | Seed client secrets moved {noop} → {bcrypt} (SSO-741); per-service AES key backup and Vault-at-deploy design are tracked. | SSO-2101 / SSO-2137 / SSO-2129 / SSO-2139 (tracked) |
| CI security guards as hard gates | High | GAP | 29 required contexts on main; 6 security-relevant guards run on every PR but are not required, so they do not block merge — incl. outbound-url-guard-check (SSRF). | SSO-2162 (new) |
trustTestIssuers default | — | OK | TrustedTenantIssuers defaults trustTestIssuers = false; code comments confirm the live/prod state is false. | — |
| SSRF outbound-URL guard | — | OK (gating gap folded into SSO-2162) | OutboundUrlGuard + check-outbound-url-guard.sh (SSO-2095) + SecurityBoundaryArchTest exist; the discovery-doc re-validation gap was closed (SSO-2117). | SSO-2095 / SSO-2117 (tracked) |
| Cross-tenant response = 404 not 403 | — | OK | Documented privacy invariant; backed by check-no-tenant-in-customer-plane-path (whose gating gap is part of SSO-2162). | — |
| Actuator exposure | — | OK | Hub exposes only health, info, prometheus with show-details: never and gates /actuator/prometheus behind SCOPE_admin; product-api / identity expose health, info, prometheus (mgmt port kept internal, show-details: when-authorized); no env / heapdump / threaddump / shutdown / configprops anywhere. | — |
api-gateway gateway actuator endpoint | Low | UNKNOWN | api-gateway exposes the gateway endpoint (route topology) on the app port with no explicit /actuator matcher found in its security config — confirm it is not reachable from the public internet at runtime. | — |
Part A — dependency detail
Jackson — pinned safe, but the comment is a trap
bom/pom.xml pins jackson.version = 2.22.1 and imports jackson-bom before
spring-boot-dependencies so the pin wins for every transitive Jackson 2 artifact. On
2026-06-22 a batch of Jackson vulnerabilities was disclosed, including CVE-2026-54513 (RCE via a
BasicPolymorphicTypeValidator allow-list bypass, affecting 2.10.0–2.18.7, 2.19.0–2.21.3,
3.0.0–3.1.3) and CVE-2026-54512 (CVSS 9.2). 2.22.1 is one of the listed fixed versions, so
the current pin is safe.
The problem is documentation drift: the jackson.version comment block and the CLAUDE.md
"Jackson default-typing" pitfall both still describe the policy as pin to the 2.21.x LTS
line, 2.21.3 latest. 2.21.3 is below the 2.21.4 fix line and is therefore vulnerable to
the RCE. A maintainer who "corrects" the version to match the stale comment would silently
reintroduce a critical RCE. The defence-in-depth check-no-default-typing guard (a required
gate) still bans the gadget-enabling API, but the version pin is the real fix and its
description must be reconciled — tracked as SSO-2161.
Spring Boot 4.0.6 and Spring Security 7.0.5
Spring Boot 4.0.6 (released 2026-04-23) is one patch above the range CVE-2026-40976 hits
(4.0.0 through 4.0.5) — a critical default-web-security authorization bypass — so the
platform carries that fix.
Spring Boot 4.0.6 resolves Spring Security 7.0.5. That matters because the hub runs the
Spring Authorization Server with Dynamic Client Registration enabled (RFC 7591 / 7592 filter
chain), which is the exact precondition for CVE-2026-22752 (CVSS 9.6, malicious client
registration leading to stored XSS / privilege escalation / SSRF). CVE-2026-22752 is fixed in
7.0.5, so the hub is covered.
However, Spring Security 7.0.6 (2026-06-09) fixed seven further CVEs — including SAML
processing, XSS, open-redirect, and X.509 handling — and 7.0.5 predates that batch. The
platform ships saml-member, which consumes spring-security-saml2-service-provider, so the
SAML-processing CVE is a live surface. The recommendation is to evaluate bumping to the Spring
Boot patch that pulls Spring Security 7.0.6 or later (or overriding the managed version),
after triaging which of the seven June CVEs affect used surfaces — tracked as SSO-2160.
Bouncy Castle, Nimbus, and the long tail
Bouncy Castle bcprov-jdk18on 1.85 clears CVE-2025-8885 (ASN.1 DoS, affects ≤ 1.77) and
CVE-2026-0636 (LDAP injection, affects 1.74 through 1.83). The bom originally pinned
only bcprov, so a live resolve found bcpkix-jdk18on / bcutil-jdk18on still arriving
transitively at 1.77 (saml-member: opensaml-security-api 5.1.6 → cryptacular 1.2.6) — a
version skew against the 1.85 provider that also carried CVE-2025-8916 (MODERATE, fixed
1.79) and CVE-2026-5588 (MODERATE, fixed 1.84). SSO-2224 pins bcpkix + bcutil to the
same ${bouncycastle.version} = 1.85, so all three -jdk18on artifacts resolve
consistently and both advisories clear.
Nimbus JOSE+JWT 10.9.1 carries the historical CVE-2024-21235 algorithm-confusion class, which
is structurally mitigated by the required jwt-decoder-algorithm-check — every decoder must pin
an ES256 allow-list, so a JWKS advertising a weaker or none algorithm is rejected.
The remaining pins (okhttp 5.4.0, pdfbox 3.0.8, bucket4j 8.10.1, twilio 12.1.1, tink
1.23.0, geoip2 5.2.0, pact 4.7.3 in test scope) showed no known high or critical CVE at
the pinned versions on the audit date. They post-date the training cut-off, so this is a
knowledge-based clearance and a live osv-scanner / OWASP Dependency-Check run should confirm it.
OpenTelemetry and Logback — the MODERATE/LOW residual (SSO-2239)
The same post-SSO-2224 full-reactor resolve that cleared the Critical/High backlog also surfaced two advisories below that bar. They were deferred from SSO-2224 — each needs a coordinated multi-artifact bump ahead of a Boot-managed BOM — and are remediated under SSO-2239:
- OpenTelemetry. Spring Boot
4.0.6manages the wholeio.opentelemetry:*family (api / context / sdk-* / exporter-*, 14 artifacts) at1.55.0, which carries CVE-2026-45292 (MODERATE, GHSA-rcgg-9c38-7xpx): unbounded memory allocation and CPU consumption in W3C baggage propagation, fixed1.62.0. Pinned by importingio.opentelemetry:opentelemetry-bom1.62.0beforespring-boot-dependencies— the same first-declared-wins mechanism asnetty-bom/protobuf-bom. The separateio.opentelemetry.semconv:*line (1.37.0, a different groupId not managed by that BOM) is outside the advisory and left untouched. - Logback. Boot
4.0.6manageslogback-classic/logback-core1.5.32, carrying CVE-2026-10532 (LOW, fixed1.5.34) and CVE-2026-9828 (LOW, fixed1.5.33) — object-injection / deserialization viaHardenedObjectInputStream, reachable only when the receiver-side hardened stream is explicitly enabled (not the default). Bumped to1.5.34. Logback publishes no BOM, and — as the tomcat / postgresql / scram overrides already record — a<logback.version>property alone cannot reach the imported Boot BOM, so both artifacts are pinned via explicit dependencyManagement entries (referencing alogback.versionproperty) before thespring-boot-dependenciesimport.
A fresh full-reactor mvn dependency:tree confirms io.opentelemetry:* resolves to 1.62.0
and logback-classic / logback-core to 1.5.34, with no other managed version regressed.
These are the last of the dependency-CVE residuals the SSO-2224 resolve surfaced; the only
remaining flagged finding is the test-scope protobuf-java under SSO-2225.
The scanning gate itself
Three scanners exist but none blocks a PR:
- OWASP Dependency-Check (
security-scan.yml) runs weekly and on push tomainwithfailBuildOnCVSS=11— so it never fails on a finding — and with noNVD_API_KEY, so the keyless NVD sync is rate-limited and the scan is explicitly advisory. - osv-scanner (
security-scan-deps.yml) runs weekly and opens a GitHub issue on critical/high findings; it never fails CI. This workflow exists precisely because a public RCE (CVE-2025-55182) reached the team via a researcher email rather than internal detection. - SpotBugs / FindSecBugs runs weekly and on push, wrapped so it never fails.
For a platform entering production, a vulnerable dependency can merge and ship, surfacing only
at the next weekly run. Adding an NVD_API_KEY, lowering failBuildOnCVSS, and/or running
osv-scanner per-PR blocking on critical is the fix — already tracked as SSO-1620 and
SSO-742.
Update (2026-07-24, SSO-742). The gate is now wired. OWASP Dependency-Check drops to
failBuildOnCVSS=7(root pom +security-scan.yml) with a suppression file for reviewed exceptions; osv-scanner (security-scan-deps.yml) now fails the job on Critical/High. Both gained apull_requesttrigger. Two findings emerged while wiring this:
- osv-scanner had been a silent no-op. Its step used osv-scanner v1 syntax (
--recursive --skip-git --json) against the pinned v2.3.8 binary, which rejects those flags (flag provided but not defined: -skip-git, exit 127);|| trueswallowed the error, so every weekly run reported "0 findings" without scanning. Corrected toscan source -r --include-git-root --format json.- The dependency set is not clean once osv-scanner actually runs. It surfaces real Spring-Boot-4.0.6-managed transitive HIGHs the NVD-focused pass above did not cover:
io.netty4.2.12.Final(up to CVSS 8.7; fixed in 4.2.15/16) and Jackson 3tools.jackson.core:jackson-core3.1.2(CVSS 8.7; fixed in 3.1.4). The audit's Jackson row clearedcom.fasterxml.jackson2.x but did not review thetools.jackson(Jackson 3) surface Spring Boot 4 actually ships.Because a threshold-7 gate trips on that backlog today, both scanners are kept non-required in branch protection (they are not in the 29 required contexts) — they fail visibly on a PR but do not block merge-on-required-green. Remediation of the transitive HIGHs and promotion to required checks is tracked as SSO-2195 (relates SSO-2162).
Part B — posture detail
The required-check gap is the load-bearing posture finding
Architecture and security invariants are enforced by a family of scripts/check-*.sh guards
wired into ci.yml (see CI security guards). The GitHub API shows main
requires 29 status-check contexts (strict: true, no rulesets). The required set covers the
highest-value invariants — the reactive-.block(), JWT-algorithm, custom-error-shape, MDC,
raw-cookie, default-typing, host-header, pod-security-context, SA-token, ingress-TLS, and
literal-secret guards are all required.
But several security-relevant guards run on every PR (confirmed: no event if: gate) yet are
absent from the required set, so a merge on required-green does not block on their failure:
outbound-url-guard-check— the SSRF outbound-URL guard coverage (SSO-2095). This is the standout: the SSRF boundary recurred four times (SSO-790 / 791 / 795 / 796) and SSO-2117 only just closed a discovery-doc re-validation gap. A change that drops anOutboundUrlGuardcall could merge on green.no-tenant-in-customer-plane-path-check— tenant-isolation, no tenant id in a URL path (SSO-1937). See tenant isolation.audit-internal-k8s-enabled-check— the internal audit endpoint must require Kubernetes ServiceAccount-JWT auth rather thanpermitAll(SSO-1337).no-noop-secret-in-migration-check— bans a cleartext{noop}client secret in a migration (SSO-741).no-unbounded-varchar-checkandencryption-key-secrets-backed-up-check— data-safety and DR.
The compensating control is the pr-merger running scripts/local-ci/pr-check.sh (which runs all
guards), but that path is unenforced. Because these jobs already report on every PR, promoting
them into required_status_checks will not deadlock open PRs — tracked as SSO-2162.
TLS
SSL-bundle references default via #{null} across the Spring services, so an unset bundle
env-var yields a plaintext client rather than a boot-time NoSuchSslBundleException. Ingress
TLS annotations are enforced by the required ingress-tls-annotations-check. The one open TLS
item is the expired staging hub wildcard certificate, already tracked at High as SSO-2119 —
referenced here, not re-filed.
NetworkPolicy
The namespace-wide baseline (network-policy-default-deny.yaml) has two halves behind one
kill-switch. The ingress half is enabled in staging (networkPolicy.enabled: true), so
default-deny-ingress plus per-destination allows are in force. The egress half is gated
separately by networkPolicy.egressEnabled, which is false in staging and false by default
in values.yaml; there is no prod values file yet, so a prod deploy that does not set it inherits
no namespace-wide egress default-deny. This is the deliberate outcome of SSO-1797, which
removed a per-service egress policy that was causing audit-emission failures — so egress
default-deny is intentionally deferred, not forgotten. The hub still carries its own per-service
egress NetworkPolicy (a CVE-2025-55182 follow-up, enabled in staging) that restricts hub egress
and denies the cluster-internal private ranges, which is the SSRF-relevant defence-in-depth
layer. The prod-values decision on the namespace-wide egress baseline should be made explicitly
at cutover; it belongs under SSO-1481 and references SSO-1797.
Secrets
The operator-set-secret posture (per-service AES key backup and DR set, Vault-at-deploy for prod
client secrets) is already captured across SSO-2129 (done), SSO-2101, SSO-2137, and
SSO-2139 — referenced here, not duplicated. The historically git-known seed client-secret
gap was closed by moving the seed family to {bcrypt} (SSO-741); the residual is that the guard
preventing a {noop} regression is not yet a required check, which is folded into SSO-2162.
Actuator
Actuator exposure is tight, not wide-open. The hub exposes only health, info, prometheus, sets
show-details: never, and gates /actuator/prometheus behind SCOPE_admin; /actuator/health
and /actuator/info are the only permitAll actuator paths. product-api and identity-service
expose health, info, prometheus with the management surface kept internal behind the gateway
and show-details: when-authorized. No service exposes env, heapdump, threaddump,
shutdown, configprops, or beans. The one item to confirm at runtime is that the
api-gateway's gateway actuator endpoint (route topology) is not reachable from the public
internet — an UNKNOWN that a live probe settles.
Tickets — newly filed vs. already tracked
Newly filed (all linked to the prod-readiness epic SSO-1481):
- SSO-2160 (Medium) — bump Spring Security past
7.0.5to pick up the7.0.6June-2026 CVE batch; SAML surface is live. - SSO-2161 (Low) — reconcile the
jackson.versioncomment drift so no one reverts to the CVE-vulnerable2.21.3. - SSO-2162 (High) — promote the SSRF / tenant-isolation / audit-auth / secret guards into
required_status_checksso they actually gate merges. - SSO-2195 (High, filed 2026-07-24 via SSO-742) — remediate the Spring-Boot-4-managed
transitive HIGHs (netty, Jackson 3) surfaced once osv-scanner actually runs, then promote the
now-wired CVE-scan jobs into
required_status_checks.
Referenced, not re-filed (already tracked):
- SSO-2119 — expired staging hub wildcard TLS cert (High).
- SSO-1797 — the egress-NetworkPolicy relaxation that leaves egress default-deny off.
- SSO-2101 / SSO-2137 / SSO-2129 / SSO-2139 — operator-set / seed secret posture.
- SSO-2095 / SSO-2117 — SSRF outbound-URL guard and its discovery-doc fix.
- SSO-1620 / SSO-742 —
NVD_API_KEYand turning the CVE scan into a real gate.
What still needs a live scan or pentest
- A live
mvn dependency:treeto confirm the resolved Spring Security version and to catch any other transitive drift the managed BOM introduces. - A keyed osv-scanner / OWASP Dependency-Check run to confirm the long-tail clearance above and to catch anything disclosed after the audit date.
- A runtime probe of the deployed cluster: actual ingress TLS, actual CNI NetworkPolicy
enforcement, and whether any actuator endpoint (notably the api-gateway
gatewayendpoint) is reachable from the public internet. - A full penetration test of the auth flows — this static pass does not exercise the OAuth, DCR, SAML, or token-revocation paths against a running system.
Source: bom/pom.xml; .github/workflows/ci.yml, security-scan.yml, security-scan-deps.yml;
.github/dependabot.yml; deploy/helm/thoryn/templates/network-policy-default-deny.yaml and
values*.yaml; servers/authorization-hub/src/main/resources/application.yaml;
servers/authorization-hub/.../config/ResourceServerConfig.kt;
core/lib/common/.../security/TrustedTenantIssuers.kt; GitHub branch-protection API; public CVE
advisories retrieved on the audit date.