The official MicroProfile JWT 2.1 TCK verifies that an implementation correctly accepts, rejects and exposes a wide range of forged tokens against an Arquillian reference application — inline keys, JWKS, JWE, standard claims, MP claims, Authorization and cookie transport, key rotation, falsified signatures, exp / nbf / iat at the boundaries. Cervantes passes it at 206 / 206 on the 2.1 release (May 2026, milestone M6).
Status
| Metric | Value |
|---|---|
Tests executed |
206 |
Passed |
206 ✅ |
Failed |
0 |
Errors |
0 |
Skipped |
0 |
Any future regression must be logged in the repository’s TCK.md with: test name, reason, remediation plan.
Prerequisites
The org.eclipse.microprofile.jwt:microprofile-jwt-auth-tck:2.1 artefact (and its tests classifier) is now available on Maven Central — it is downloaded automatically. The runner also installs cassini-tck into the local M2 to provide CassiniTestHarness.
sdk env # Java 25 + Maven 3.9.16
./mvnw -ntp install -DskipTests # installs cervantes-core, cervantes-jaxrs, cervantes-cdi-vauban, …
Runner execution
The run-official-tck-mp-jwt-2.1.sh script at the repository root drives every variant.
# Smoke — single fast test to validate the installation
./run-official-tck-mp-jwt-2.1.sh
# Full suite — equivalent to the official 206-test TCK
./run-official-tck-mp-jwt-2.1.sh all
# Targeted test via -Dtest=
./run-official-tck-mp-jwt-2.1.sh -Dtest=PublicKeyAsPEMTest
The runner uses Arquillian. The Surefire report lands in cervantes-tck/target/surefire-reports/.
Runner architecture
cervantes-tck is in-reactor behind the tck Maven profile of cervantes-parent (TCK harmonisation, vidocq-runtime-tck-* pattern): a plain mvn install never builds nor downloads it. Direct invocation: ./mvnw -P"tck,smoke" -pl cervantes-tck test (smoke) or ./mvnw -P"tck,tck-official" -pl cervantes-tck test (full suite). Template originally mirrored from heisenberg-tck.
|
The runner was historically detached from the reactor (standalone |
Stack assembled by the runner:
| Layer | Component |
|---|---|
Spec |
|
MP JWT implementation |
|
CDI container |
Vauban ( |
Arquillian container |
|
HTTP transport |
Chappe ( |
Test framework |
Arquillian + REST (the MP JWT TCK is not TestNG-only, unlike the MP FT TCK) |
Documented exclusions
Two exclusions, not applicable to the Core + JWT profile targeted by Cervantes:
| Exclusion | Justification |
|---|---|
Tests under |
Tests targeting the Jakarta EE Full container servlet profile. Cervantes targets the Core (MicroProfile) profile — no Servlet 6.1 commitment. The Servlet role is filled by Foy, out of scope for this MP JWT implementation. |
TestNG group |
Tests marked optional by the spec for Jakarta EE Security 3.0 integration. Not required for MP JWT 2.1 conformance. |
The exclusions are listed in the Arquillian/TestNG suite file under cervantes-tck/src/test/resources/. Any future exclusion must be tracked in TCK.md with its justification.
Gaps resolved during the race to 100 %
The TCK surfaced several gaps between the spec and the initial implementation; every one of them was fixed in the engine, not masked by exclusions:
| Component | Resolved gap |
|---|---|
|
Lazy HTTP load + PEM-vs-JWKS auto-detection on the same URL + URL re-read after the server starts (the port is only known after bind). |
|
Added |
|
Parsing of JWK private key ( |
|
Explicit required-algorithm check + |
|
|
|
Unwrap |
|
Cookie-based token extraction (§9.2.3), error-case distinction, anonymous behaviour on missing token. |
|
Anonymous principal → |
Prerequisites delivered upstream
Two external fixes were necessary to reach 206/206:
-
cassini —
@Context SecurityContextpatch injected into a resource to reflect the JWT fromJwtAuthenticationFilter. Merged on Cassini main, REST TCK 4.0 (2535 tests) preserved. -
vauban — VAU-INJ-PRIM fix:
TypeMapperwas exposing a primitive injection point (boolean) asClassType[name=boolean]instead ofPrimitiveType, silently breaking@Claim booleaninjection. Fix + regression testPrimitiveQualifiedInjectionTest. Merged on Vauban main.