Skip to content
Flag of Europe
Made in the European Union · Independently built · Released under EUPL 1.2

00.76.00

Available on Maven Central. A complete, RFC-conformant JWT validation stack as an opt-in module — the crypto / validation base for the OAuth2 (00.77) and OIDC-RP (00.78) layers. Additive — consumers without a JWT pull neither Nimbus nor BouncyCastle; every 00.73–00.75 app compiles and boots identically. No migration. Since hardened by 00.76.10; the current release is 00.79.41.

Release date: 2026-06-25 Previous release: 00.75.20 Maven coordinates (parent): com.svenruppert.jsentinel:jSentinel-parent:00.76.00 Full changelog: GitHub release v00.76.00

Before 00.76, bearer tokens were opaque strings and every RestSubjectResolver re-implemented signature / exp / iss / aud checks. Now JWT validation is a first-class, hardened building block.

Headline — validate a JWT in three config lines

RestSecurity.bootstrap()
    .mode(SecurityBootstrapMode.PRODUCTION)
    .jwt(j -> j
        .jwksUri(URI.create("https://idp.example/.well-known/jwks.json"))
        .algorithmProfile(AlgorithmProfile.STRICT_MODERN)
        .issuer("https://idp.example/")
        .audience("api.example"))
    .install();

A RestSubjectResolver then validates via JSentinelServiceResolver.findJwtValidator() and binds an OidcAccessToken.fromValidated(...).

What’s new

  • jSentinel-jwt — the new opt-in module: a Nimbus JOSE+JWT-backed NimbusJwtValidator, an HttpJwksClient with a disciplined cache, NimbusJwtValidatorFactory and a JwtDiagnosticContributor. The only module on the reactor with a JOSE library on the classpath.
  • JOSE-free core SPIs (jSentinel-core/jwt/api) — JwtValidator, ValidatedJwt, a sealed JwtValidationError, JoseHeader, JwsAlgorithm, AlgorithmAllowList / AlgorithmProfile, ClaimExpectations, ClockSkewPolicy, JwksClient, JwtValidatorFactory / JwtValidatorSpec — 12 Result-based types, sealed errors with kebab-case codes.
  • .jwt(...) fluent bootstrap (jSentinel-dx) — adapter-symmetric across Vaadin / REST / Standalone; the DX layer discovers the Nimbus factory via ServiceLoader and never compiles against a JOSE type.
  • Inbound OIDCOidcInboundTokenValidator in jSentinel-propagation-oidc (core SPI only; the JOSE-enforcer ban stays intact).
  • Events — four JSentinelEvent types (JwtValidationSucceeded / Failed, JwksRefreshed / RefreshFailed), non-secret payloads only.
  • Demo — a demo-rest /api/jwt/demo route with a Nimbus JwtIssuerStub, end to end.

Security posture

A mandatory algorithm allow-list (no implicit allow-all) with hard algorithm-confusion defencealg:none, HMAC-with-asymmetric-key and alg/key-family mismatch are all rejected; asymmetric-only (RS / PS / ES / EdDSA). Strict iss exact-match + aud intersection. The JWKS client cannot be turned into a DoS against the IdP — TTL from Cache-Control: max-age, single-flight refresh on a kid miss, a 30 s negative cache and a 1 MiB body cap. EdDSA runs on the JDK’s native provider (no Google Tink). All vectors are adversarially tested with no mocks (real Nimbus issuers, a real JDK HttpServer JWKS stub).

Additivity

Additive over 00.73 / 00.74 / 00.75. The only core changes are additive: OidcAccessToken gains a fifth optional validated component (the TokenCredential permits clause is unchanged), the jwt/api package is new, and JSentinelServiceResolver gains a find/setJwtValidator pair. No 00.74/00.75 STRICT code is promoted; the new STRICT codes (jwt/no-algorithm-allow-list, jwks/uri-not-https, …) only fire when .jwt(...) is actually used. All 00.76 public types carry @ExperimentalJSentinelApi.

What it does not do

No OAuth2 flows (00.77), no OIDC discovery / ID-token semantics (00.78), no JWE / DPoP / vendor profiles (00.79), no JWT signing, no symmetric (HMAC) JWT.

Quality

jSentinel-jwt gets its first PIT baseline at 66 % (76/116); the survivors cluster in JWKS-cache timing/guard branches. Every touched 00.71–00.75 module retains its baseline by construction (00.76 only adds tested code and additive fields). Full-reactor clean install green across all 40 modules; entry + exit production reviews executed with all mandatory findings fixed in-cycle. No mocks.

Migration

None. The JWT stack is opt-in; apps that don’t call .jwt(...) pull no new dependency. Just bump the version to 00.76.00.