Status List Lifecycle¶
| Field | Value |
|---|---|
| Level | Intermediate |
| Maturity | Stable |
| Runnable | Conceptual (paste into a console app) |
| Packages | SdJwt.Net.Vc, SdJwt.Net.StatusList |
| Standards | SD-JWT VC draft-16, Token Status List draft-20 |
This example demonstrates the credential status lifecycle:
- Issue a credential with a status list reference.
- Publish the status list token.
- Verify the credential is active.
- Revoke the credential.
- Verify the credential is now rejected.
1. Setup: Create a Status List¶
using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
using SdJwt.Net.StatusList.Issuer;
using SdJwt.Net.StatusList.Models;
var issuerKey = ECDsa.Create(ECCurve.NamedCurves.nistP256);
var signingKey = new ECDsaSecurityKey(issuerKey);
// Create a status list manager
// The list tracks credential status at assigned indices
var statusListManager = new StatusListManager(new StatusListManagerOptions
{
Issuer = "https://issuer.example.com",
StatusListUri = "https://issuer.example.com/.well-known/status-list",
SigningKey = signingKey,
Algorithm = SecurityAlgorithms.EcdsaSha256,
BitsPerStatus = 2 // Supports: 0=valid, 1=revoked, 2=suspended
});
2. Issue Credential with Status Reference¶
When issuing a credential, embed a status claim pointing to the issuer's status list.
// Allocate an index in the status list for this credential
int credentialIndex = statusListManager.AllocateIndex();
// The status reference to embed in the SD-JWT VC
var statusReference = new StatusListReference
{
Uri = "https://issuer.example.com/.well-known/status-list",
Index = credentialIndex
};
// Include the status claim when issuing the SD-JWT VC
// (See issuer-wallet-verifier.md for full issuance flow)
var credentialClaims = new Dictionary<string, object>
{
["vct"] = "https://credentials.example.com/identity_credential",
["iss"] = "https://issuer.example.com",
["iat"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
["given_name"] = "Alice",
["status"] = new Dictionary<string, object>
{
["status_list"] = new Dictionary<string, object>
{
["idx"] = credentialIndex,
["uri"] = statusReference.Uri
}
}
};
Console.WriteLine($"Credential issued at status index: {credentialIndex}");
3. Publish the Status List Token¶
The issuer publishes the status list as a signed JWT at the well-known URI.
// Generate the signed status list token
string statusListToken = statusListManager.CreateStatusListToken();
// Serve this token at: GET https://issuer.example.com/.well-known/status-list
// Content-Type: application/statuslist+jwt
Console.WriteLine("Status list token published.");
4. Verify Credential Status (Active)¶
using SdJwt.Net.StatusList.Verifier;
var statusVerifier = new StatusListVerifier();
var statusResult = await statusVerifier.CheckAsync(
statusListToken,
credentialIndex,
new StatusListOptions
{
IssuerSigningKey = new ECDsaSecurityKey(
ECDsa.Create(issuerKey.ExportParameters(false)))
});
Console.WriteLine($"Status check result: {statusResult.Status}");
// Output: Status check result: Valid
Console.WriteLine($"Is active: {statusResult.IsActive}");
// Output: Is active: True
5. Revoke the Credential¶
// Issuer revokes the credential by updating the status list
statusListManager.SetStatus(credentialIndex, StatusType.Revoked);
// Re-publish the updated status list token
string updatedStatusListToken = statusListManager.CreateStatusListToken();
Console.WriteLine("Credential revoked. Updated status list published.");
6. Verify After Revocation (Rejected)¶
var revokedResult = await statusVerifier.CheckAsync(
updatedStatusListToken,
credentialIndex,
new StatusListOptions
{
IssuerSigningKey = new ECDsaSecurityKey(
ECDsa.Create(issuerKey.ExportParameters(false)))
});
Console.WriteLine($"Status after revocation: {revokedResult.Status}");
// Output: Status after revocation: Revoked
Console.WriteLine($"Is active: {revokedResult.IsActive}");
// Output: Is active: False
Status Values¶
| Value | Meaning | Description |
|---|---|---|
| 0 | Valid | Credential is active |
| 1 | Revoked | Permanently invalidated |
| 2 | Suspended | Temporarily inactive, can be resumed |
Expected Outcomes¶
| Step | Result |
|---|---|
| Issue with status | Credential includes status reference |
| Check active | IsActive = true |
| Revoke | Status list updated at index |
| Check after revoke | IsActive = false, Status = Revoked |
Related¶
- Issuer - Wallet - Verifier -- full issuance and presentation flow
- Federated Trust Verification -- resolve issuer trust
- Token Status List spec