
Implements Token Status List Specification, enabling status checks for tokens like valid, revoked, or suspended. Supports JWT format and offers interfaces for fetching and reading status lists.
❗ Important! Before you proceed, please read the EUDI Wallet Reference Implementation project description
Statium is a Kotlin multiplatform library supporting JVM and Android platforms. It implements the Token Status List Specification draft 12, and allows callers to check the status of a "Referenced Token" as defined in the specification, effectively enabling applications to verify if tokens are valid, revoked, or in other states.
[!NOTE] Currently, Statium supports JWT format for the Status List Token.
The released software is an initial development release version:
To include the Statium library in your project, add the following dependency:
// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium:$statium_ver")
}// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium-jvm:$statium_ver")
}// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium-android:$statium_ver")
}Statium uses Ktor to perform HTTP Requests. Statium doesn't use a specific Client Engine. To use Statium in your project, configure your preferred Client Engine implementation as well.
A list of available Client Engines can be found here
For instance, to use OkHttp add the following dependency:
dependencies {
implementation("io.ktor:ktor-client-okhttp:$ktor_version")
}As a Relying Party fetch a Status List Token.
Library provides for this use case the interface GetStatusListToken
// Create an instance of GetStatusListToken using the usingJwt factory method
val getStatusListToken: GetStatusListToken = GetStatusListToken.usingJwt(
clock = Clock.System,
httpClient = HttpClient(), // Just an example, remember to close the client when you're done!
verifyStatusListTokenSignature = VerifyStatusListTokenJwtSignature.Ignore, // Not for production
allowedClockSkew = 5.minutes // Allow 5 minutes of clock skew (requires import: kotlin.time.Duration.Companion.minutes)
)
// Use the GetStatusListToken instance to fetch a status list token
val uri = "https://example.com/status-list"
val result = getStatusListToken(uri, null) // null means "now"
// Handle the result
val claims : StatusListTokenClaims = result.getOrThrow()
println("Status list token claims: $claims")[!NOTE] Statium supports JWT and CWT formats (using COSE Sign 1)
[!IMPORTANT] Statium doesn't verify the signature of the JWT or the CWT, given that Token Status List specification lets ecosystems define their own processing rules. For this reason, you need to provide an implementation of VerifyStatusListTokenJwtSignature, or use VerifyStatusListTokenCwtSignature. This will be used to verify the signature of the Status List Token after it has been fetched.
As a Relying Party be able to read a Status List at a specific index.
It is assumed that the caller has already fetched
the Status List (via a Status List Token)
Library provides for this use case the interface ReadStatus
// Assuming you have already got a StatusListTokenClaims
val claims: StatusListTokenClaims = obtainStatusListTokenClaims() // This function is not shown here
val readStatus: ReadStatus = ReadStatus.fromStatusList(claims.statusList).getOrThrow()
val status = readStatus(StatusIndex(5)).getOrThrow() // check index 5
// Pattern match on status
when (status) {
Status.Valid -> println("Token is valid")
Status.Invalid -> println("Token is invalid")
Status.Suspended -> println("Token is suspended")
is Status.ApplicationSpecific -> println("Application-specific status: ${status.value}")
is Status.Reserved -> println("Reserved status: ${status.value}")
}As a Relying Party fetch the corresponding Status List Token
to validate the status of that Referenced Token
It is assumed that the caller has extracted from the Referenced Token
a reference to a status_list.
Library provides for this use case the interface GetStatus
// Create an instance of GetStatusListToken (as shown in the Get Status List Token section)
val getStatusListToken: GetStatusListToken = TODO("Check above")
// Create an instance of GetStatus using the GetStatusListToken
val getStatus = GetStatus(getStatusListToken)
// Assuming you have a StatusReference from a Referenced Token
val statusReference = StatusReference(
index = StatusIndex(42),
uri = "https://example.com/status-list"
)
// Use the GetStatus instance to check the status of the Referenced Token
val status = runBlocking {
with(getStatus) {
statusReference.status(at = null).getOrThrow() // null means "now"
}
}
// Handle the result
when (status) {
Status.Valid -> println("Token is valid")
Status.Invalid -> println("Token is invalid")
Status.Suspended -> println("Token is suspended")
is Status.ApplicationSpecific -> println("Application-specific status: ${status.value}")
is Status.Reserved -> println("Reserved status: ${status.value}")
}We welcome contributions to this project. To ensure that the process is smooth for everyone involved, follow the guidelines found in CONTRIBUTING.md.
Copyright (c) 2025-2026 European Commission
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
❗ Important! Before you proceed, please read the EUDI Wallet Reference Implementation project description
Statium is a Kotlin multiplatform library supporting JVM and Android platforms. It implements the Token Status List Specification draft 12, and allows callers to check the status of a "Referenced Token" as defined in the specification, effectively enabling applications to verify if tokens are valid, revoked, or in other states.
[!NOTE] Currently, Statium supports JWT format for the Status List Token.
The released software is an initial development release version:
To include the Statium library in your project, add the following dependency:
// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium:$statium_ver")
}// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium-jvm:$statium_ver")
}// build.gradle.kts
dependencies {
implementation("eu.europa.ec.eudi:eudi-lib-kmp-statium-android:$statium_ver")
}Statium uses Ktor to perform HTTP Requests. Statium doesn't use a specific Client Engine. To use Statium in your project, configure your preferred Client Engine implementation as well.
A list of available Client Engines can be found here
For instance, to use OkHttp add the following dependency:
dependencies {
implementation("io.ktor:ktor-client-okhttp:$ktor_version")
}As a Relying Party fetch a Status List Token.
Library provides for this use case the interface GetStatusListToken
// Create an instance of GetStatusListToken using the usingJwt factory method
val getStatusListToken: GetStatusListToken = GetStatusListToken.usingJwt(
clock = Clock.System,
httpClient = HttpClient(), // Just an example, remember to close the client when you're done!
verifyStatusListTokenSignature = VerifyStatusListTokenJwtSignature.Ignore, // Not for production
allowedClockSkew = 5.minutes // Allow 5 minutes of clock skew (requires import: kotlin.time.Duration.Companion.minutes)
)
// Use the GetStatusListToken instance to fetch a status list token
val uri = "https://example.com/status-list"
val result = getStatusListToken(uri, null) // null means "now"
// Handle the result
val claims : StatusListTokenClaims = result.getOrThrow()
println("Status list token claims: $claims")[!NOTE] Statium supports JWT and CWT formats (using COSE Sign 1)
[!IMPORTANT] Statium doesn't verify the signature of the JWT or the CWT, given that Token Status List specification lets ecosystems define their own processing rules. For this reason, you need to provide an implementation of VerifyStatusListTokenJwtSignature, or use VerifyStatusListTokenCwtSignature. This will be used to verify the signature of the Status List Token after it has been fetched.
As a Relying Party be able to read a Status List at a specific index.
It is assumed that the caller has already fetched
the Status List (via a Status List Token)
Library provides for this use case the interface ReadStatus
// Assuming you have already got a StatusListTokenClaims
val claims: StatusListTokenClaims = obtainStatusListTokenClaims() // This function is not shown here
val readStatus: ReadStatus = ReadStatus.fromStatusList(claims.statusList).getOrThrow()
val status = readStatus(StatusIndex(5)).getOrThrow() // check index 5
// Pattern match on status
when (status) {
Status.Valid -> println("Token is valid")
Status.Invalid -> println("Token is invalid")
Status.Suspended -> println("Token is suspended")
is Status.ApplicationSpecific -> println("Application-specific status: ${status.value}")
is Status.Reserved -> println("Reserved status: ${status.value}")
}As a Relying Party fetch the corresponding Status List Token
to validate the status of that Referenced Token
It is assumed that the caller has extracted from the Referenced Token
a reference to a status_list.
Library provides for this use case the interface GetStatus
// Create an instance of GetStatusListToken (as shown in the Get Status List Token section)
val getStatusListToken: GetStatusListToken = TODO("Check above")
// Create an instance of GetStatus using the GetStatusListToken
val getStatus = GetStatus(getStatusListToken)
// Assuming you have a StatusReference from a Referenced Token
val statusReference = StatusReference(
index = StatusIndex(42),
uri = "https://example.com/status-list"
)
// Use the GetStatus instance to check the status of the Referenced Token
val status = runBlocking {
with(getStatus) {
statusReference.status(at = null).getOrThrow() // null means "now"
}
}
// Handle the result
when (status) {
Status.Valid -> println("Token is valid")
Status.Invalid -> println("Token is invalid")
Status.Suspended -> println("Token is suspended")
is Status.ApplicationSpecific -> println("Application-specific status: ${status.value}")
is Status.Reserved -> println("Reserved status: ${status.value}")
}We welcome contributions to this project. To ensure that the process is smooth for everyone involved, follow the guidelines found in CONTRIBUTING.md.
Copyright (c) 2025-2026 European Commission
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.