This project is not actively being maintained. If you are interested in adopting it, please open an issue.
Credential Status
Though VCs are designed to give the holder a large degree of freedom in using their data, credential issuers are able to retain some control over the data they attest to after issuance. One of the mechanisms by which they retain this control is through the usage of credential status.
Credential status can be implemented through any valid JSON-LD type, to specify any status such as whether a credential is suspended
or revoked
. The most prominently used type is the Status List.
To make use of credential status, issuers must follow the rules outlined in the Status List specification to build a status list credential, and then include the requisite values in the credentialStatus
property of any VC they issue according to the Status List Entry portion of the specification.
How does Status List work?
Status List provides:​
- Issuers a mechanism to express the status of a given credential.
- Verifiers a mechanism to check the status of a given credential.
- Holders a set of privacy guarantees about status checks for credentials they hold.
The way this works with SSI Service:​
Issuers create a new credential using bitstring that represents credential statuses that are unique for each <issuer, credential schema>
pair.
Then, for each new credential an issuer creates for a given schema:
- A new credential status credential is created or an existing credential status credential is used.
- The credentials contain a reference to the status list credential contained in the credential's
credentialStatus
property, which can be used by verifiers to check the status of the credential.
Bitstring and Herd Privacy:​
Status credentials use a bitstring which can provide herd privacy for credential holders. In simpler terms this means that many credentials can be represented in a single bitstring, so it is not clear which credential/holder a verifier is requesting information about which is great for holder privacy.
"Credential Status" Credential​
Here is an example of a status list credential. Note that in addition to being of type VerifiableCredential
, it is also of type StatusList2021Credential
. Also note the credentialSubject.type
property is set to Status2021
:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/vc/status-list/2021/v1"
],
"id": "https://example.com/credentials/status/3",
"type": ["VerifiableCredential", "StatusList2021Credential"],
"issuer": "did:example:12345",
"issued": "2021-04-05T14:27:40Z",
"credentialSubject": {
"id": "https://example.com/status/3#list",
"type": "StatusList2021",
"statusPurpose": "revocation",
"encodedList": "H4sIAAAAAAAAA-3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
},
"proof": { ... }
}
Credential with a Credential Status​
In this example, the credential references a status list credential in the given credentialStatus
section. Also, notice that the credential also has a statusListIndex
of 94567
, which is an arbitrary integer that identifies the position of the status of the verifiable credential:
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/vc/status-list/2021/v1"
],
"id": "https://example.com/credentials/23894672394",
"type": ["VerifiableCredential"],
"issuer": "did:example:12345",
"issued": "2021-04-05T14:27:42Z",
"credentialStatus": {
"id": "https://example.com/credentials/status/3#94567",
"type": "StatusList2021Entry",
"statusPurpose": "revocation",
"statusListIndex": "94567",
"statusListCredential": "https://example.com/credentials/status/3"
},
"credentialSubject": {
"id": "did:example:6789",
"type": "Person"
},
"proof": { ... }
}
The verification process would be as follows:​
- Holder
did:example:6789
presents their credential to a verifier. - Verifier makes a request to resolve the credential status credential identified by
https://example.com/credentials/status/3
. - Upon resolution of this credential, the verifier checks the value of the bitstring at index
94567
. - If present, the credential has a
revoked
status. If absent, the credential does not have arevoked
status.
Create a Credential with Status​
Let's create a revocable credential.
Prerequsites​
- Follow guide to Run SSI Service.
- Create an issuer DID and an unsigned schema. Save the DID
id
and the schemaid
. - For testing purposes use the subject DID in our example below.
1. Create Credential​
Create a PUT
request to /v1/credentials
making sure the request body has the property revocable
set to true
:
curl -X PUT localhost:8080/v1/credentials -d '{
"issuer": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD",
"verificationMethodId": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD#z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD",
"subject": "did:key:z6MkmNnvnfzW3nLiePweN3niGLnvp2BjKx3NM186vJ2yRg2z",
"schemaId": "aed6f4f0-5ed7-4d7a-a3df-56430e1b2a88",
"data": {
"firstName": "Satoshi",
"lastName": "Nakamoto"
},
"revocable": true
}'
Upon success we should see a response such as:
{
"id": "8f9d58b2-c978-4317-96bd-35949ce76121",
"fullyQualifiedVerificationMethodId": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD#z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD",
"credential": {
"@context": ["https://www.w3.org/2018/credentials/v1"],
"id": "http://localhost:8080/v1/credentials/8f9d58b2-c978-4317-96bd-35949ce76121",
"type": ["VerifiableCredential"],
"issuer": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD",
"issuanceDate": "2023-07-31T11:18:26-07:00",
"credentialStatus": {
"id": "http://localhost:8080/v1/credentials/8f9d58b2-c978-4317-96bd-35949ce76121/status",
"statusListCredential": "http://localhost:8080/v1/credentials/status/b7a8bd19-f20d-4132-ac2e-137ff4d1511a",
"statusListIndex": "106493",
"statusPurpose": "revocation",
"type": "StatusList2021Entry"
},
"credentialSubject": {
"firstName": "Satoshi",
"id": "did:key:z6MkmNnvnfzW3nLiePweN3niGLnvp2BjKx3NM186vJ2yRg2z",
"lastName": "Nakamoto"
},
"credentialSchema": {
"id": "aed6f4f0-5ed7-4d7a-a3df-56430e1b2a88",
"type": "JsonSchema2023"
}
},
"credentialJwt": "eyJhbGciOiJFZER..."
}
Notably we see the credentialStatus
entry in the credential we've created, with id http://localhost:8080/v1/credentials/8f9d58b2-c978-4317-96bd-35949ce76121/status
and the status list credential that has been created, with id http://localhost:8080/v1/credentials/status/b7a8bd19-f20d-4132-ac2e-137ff4d1511a
.
2. Get Status List Credential​
Next, let's get the credential's associated statusListCredential
via a request to /v1/credentials/status/{id}
:
curl http://localhost:8080/v1/credentials/status/b7a8bd19-f20d-4132-ac2e-137ff4d1511a
Upon success we should see a response such as:
{
"id": "b7a8bd19-f20d-4132-ac2e-137ff4d1511a",
"credential": {
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/vc/status-list/2021/v1"
],
"id": "http://localhost:8080/v1/credentials/status/b7a8bd19-f20d-4132-ac2e-137ff4d1511a",
"type": [
"VerifiableCredential",
"StatusList2021Credential"
],
"issuer": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD",
"issuanceDate": "2023-07-31T18:18:26Z",
"credentialSubject": {
"encodedList": "H4sIAAAAAAAA/2IAAweGUTAKRsEoGAWjYBSMPAAIAAD//9BoYmEICAAA",
"id": "http://localhost:8080/v1/credentials/status/b7a8bd19-f20d-4132-ac2e-137ff4d1511a",
"statusPurpose": "revocation",
"type": "StatusList2021"
}
},
"credentialJwt": "eyJhbGciOiJFZERTQSIs..."
}
With this statusListCredential
, we're able to check the status for the credential we created, which is identified by its id
and status list index 106493
.
3. Verify Credential's Status​
To check the status for any credential, you can make a GET
request to /v1/credentials/{id}/status
. Using our credential's "id": "b7a8bd19-f20d-4132-ac2e-137ff4d1511a"
, here's how we would make the request:
curl localhost:8080/v1/credentials/8f9d58b2-c978-4317-96bd-35949ce76121/status
Upon success, we should see a response saying the credential is neither revoked or suspended:
{
"revoked": false,
"suspended": false
}
Next Steps​
Learn how to revoke this credential.
Was this page helpful?
Connect with us on Discord
Submit feedback: Open a GitHub issue
Edit this page: GitHub Repo
Contribute: Contributing Guide