.. and press ENTER to ask a question on web5, how to write code and more.

Skip to main content
warning

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 a revoked status.


Create a Credential with Status​

Let's create a revocable credential.

info

Prerequsites​

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.

Connect with us on Discord

Submit feedback: Open a GitHub issue

Edit this page: GitHub Repo

Contribute: Contributing Guide