Noting some miscellaneous issues i've ran into while testing the status_list plugin.
Can break these out into seperate tickets if further discussion is desired
OpenAPI Schema Issues
- all fields of the StatusListDef schema object are nullable/optional, why?
- list status list def results does not match schema (
[..] instead of { results: [...] })
Config Issues
- attempt to create status list without specifying
shard_size in the request body after agent launch will fail since Config is not loaded yet (also applicable for list_size)
Conformance Issues
- The returned JWT for the W3C VCDM 2 BitString status list credential does not follow standard the W3C VCDM 2.0 JOSE securing mechanism structure (
application/vc+jwt)
- the BitStringStatusListEntry credentialStatus objects returned from the assign API/function should represent
statusListIndex as a JSON string rather than as a JSON number. "123" instead of 123
According to the W3C securing VCs with JOSE spec (https://www.w3.org/TR/vc-jose-cose/#securing-with-jose) a VCDM2.0 is secured by embedding the application/vc structure (the VCDM) as the body content of the JWT.
It does not suggest that the VCDM should be embedded within a "vc": {..} field of the JWT's body content.
Therefore i don't think ACA-Py should encode it's JWT-secured BitString status list VCs with this "vc": field.
Example
ACA-Py returns this JWT for a secured bitstring status list:
eyJ0eXAiOiAiSldUIiwgImtpZCI6ICJkaWQ6a2V5OnpEbmFlcTJKcDh0SE5vbzNXZXVnczd2RlRHeFB4WHN0MU44cVdCbmdpbXRTTW41MUIjekRuYWVxMkpwOHRITm9vM1dldWdzN3ZGVEd4UHhYc3QxTjhxV0JuZ2ltdFNNbjUxQiIsICJhbGciOiAiRVMyNTYifQ.eyJpc3MiOiAiZGlkOmtleTp6RG5hZXEySnA4dEhOb28zV2V1Z3M3dkZUR3hQeFhzdDFOOHFXQm5naW10U01uNTFCIiwgIm5iZiI6IDE3NjEwMzM4NjAsICJqdGkiOiAidXJuOnV1aWQ6MSIsICJzdWIiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS8xIiwgInZjIjogeyJAY29udGV4dCI6IFsiaHR0cHM6Ly93d3cudzMub3JnL25zL2NyZWRlbnRpYWxzL3YyIl0sICJpZCI6ICJodHRwczovL2V4YW1wbGUuY29tLzEiLCAidHlwZSI6IFsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCAiQml0c3RyaW5nU3RhdHVzTGlzdENyZWRlbnRpYWwiXSwgImlzc3VlciI6ICJkaWQ6a2V5OnpEbmFlcTJKcDh0SE5vbzNXZXVnczd2RlRHeFB4WHN0MU44cVdCbmdpbXRTTW41MUIiLCAidmFsaWRGcm9tIjogIjIwMjUtMTAtMjFUMDg6MDQ6MjAuOTcxNTU5KzAwOjAwIiwgInZhbGlkVW50aWwiOiAiMjAyNi0xMC0yMVQwODowNDoyMC45NzE1NTkrMDA6MDAiLCAiY3JlZGVudGlhbFN1YmplY3QiOiB7ImlkIjogImh0dHBzOi8vZXhhbXBsZS5jb20vMSNsaXN0IiwgInR5cGUiOiAiQml0c3RyaW5nU3RhdHVzTGlzdCIsICJzdGF0dXNQdXJwb3NlIjogInJldm9jYXRpb24iLCAiZW5jb2RlZExpc3QiOiAiSDRzSUFJUS05MmdDXy0zQk1RRUFBQURDb1BWUGJRd2ZvQUFBQUFBQUFBQUFBQUFBQUFBQUFJQzNBWWJTVktzQVFBQUEifX19.ZY1J7pxvdSc3ZYXF9nNGIY80DG1WfR2wh7ytrW2nUKJ6SvCnm5HJeBrGIKvSA13bg1a-RYsKPmn5fH4cEI2SlA
which has contents of:
{
"iss": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B",
"nbf": 1761033860,
"jti": "urn:uuid:1",
"sub": "https://example.com/1",
"vc": {
"@context": [
"https://www.w3.org/ns/credentials/v2"
],
"id": "https://example.com/1",
"type": [
"VerifiableCredential",
"BitstringStatusListCredential"
],
"issuer": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B",
"validFrom": "2025-10-21T08:04:20.971559+00:00",
"validUntil": "2026-10-21T08:04:20.971559+00:00",
"credentialSubject": {
"id": "https://example.com/1#list",
"type": "BitstringStatusList",
"statusPurpose": "revocation",
"encodedList": "H4sIAIQ-92gC_-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
}
}
}
this appears to be the VCDM 1.X way of securing VCs with JWTs.
my reading is that JOSE-secured VCDM 2.0's should instead have contents like so:
{
"@context": [
"https://www.w3.org/ns/credentials/v2"
],
"id": "https://example.com/1",
"type": [
"VerifiableCredential",
"BitstringStatusListCredential"
],
"issuer": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B",
"validFrom": "2025-10-21T08:04:20.971559+00:00",
"validUntil": "2026-10-21T08:04:20.971559+00:00",
"credentialSubject": {
"id": "https://example.com/1#list",
"type": "BitstringStatusList",
"statusPurpose": "revocation",
"encodedList": "H4sIAIQ-92gC_-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
}
}
Logic Issues
- the
/status-list/assign/{supported_cred_id}/creds/{cred_id} API allows the same cred + cred ID to be bound multiple times. But then other APIs break because of this. e.g. if you try to then fetch the entry, you get 500: Multiple StatusListCred records located for {'definition_id': '08a4f43b-a0e8-48a5-b0b5-6a495dcf204c', 'credential_id': '1'}.
Noting some miscellaneous issues i've ran into while testing the status_list plugin.
Can break these out into seperate tickets if further discussion is desired
OpenAPI Schema Issues
[..]instead of{ results: [...] })Config Issues
shard_sizein the request body after agent launch will fail sinceConfigis not loaded yet (also applicable forlist_size)Conformance Issues
application/vc+jwt)statusListIndexas a JSON string rather than as a JSON number."123"instead of123According to the W3C securing VCs with JOSE spec (https://www.w3.org/TR/vc-jose-cose/#securing-with-jose) a VCDM2.0 is secured by embedding the application/vc structure (the VCDM) as the body content of the JWT.
It does not suggest that the VCDM should be embedded within a
"vc": {..}field of the JWT's body content.Therefore i don't think ACA-Py should encode it's JWT-secured BitString status list VCs with this
"vc":field.Example
ACA-Py returns this JWT for a secured bitstring status list:
which has contents of:
{ "iss": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B", "nbf": 1761033860, "jti": "urn:uuid:1", "sub": "https://example.com/1", "vc": { "@context": [ "https://www.w3.org/ns/credentials/v2" ], "id": "https://example.com/1", "type": [ "VerifiableCredential", "BitstringStatusListCredential" ], "issuer": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B", "validFrom": "2025-10-21T08:04:20.971559+00:00", "validUntil": "2026-10-21T08:04:20.971559+00:00", "credentialSubject": { "id": "https://example.com/1#list", "type": "BitstringStatusList", "statusPurpose": "revocation", "encodedList": "H4sIAIQ-92gC_-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA" } } }this appears to be the VCDM 1.X way of securing VCs with JWTs.
my reading is that JOSE-secured VCDM 2.0's should instead have contents like so:
{ "@context": [ "https://www.w3.org/ns/credentials/v2" ], "id": "https://example.com/1", "type": [ "VerifiableCredential", "BitstringStatusListCredential" ], "issuer": "did:key:zDnaeq2Jp8tHNoo3Weugs7vFTGxPxXst1N8qWBngimtSMn51B", "validFrom": "2025-10-21T08:04:20.971559+00:00", "validUntil": "2026-10-21T08:04:20.971559+00:00", "credentialSubject": { "id": "https://example.com/1#list", "type": "BitstringStatusList", "statusPurpose": "revocation", "encodedList": "H4sIAIQ-92gC_-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA" } }Logic Issues
/status-list/assign/{supported_cred_id}/creds/{cred_id}API allows the same cred + cred ID to be bound multiple times. But then other APIs break because of this. e.g. if you try to then fetch the entry, you get500: Multiple StatusListCred records located for {'definition_id': '08a4f43b-a0e8-48a5-b0b5-6a495dcf204c', 'credential_id': '1'}.