IMPORTANT NOTE ABOUT VERSIONING: If you are using a Docker Hub image of this repository, make sure you are reading the version of this README that corresponds to your Docker Hub version. If, for example, you are using the image digitalcredentials/status-service-db:0.1.0
then you'll want to use the corresponding tagged repo: https://github.com/digitalcredentials/status-service-db/tree/v0.1.0.
A microservice (running as a nodejs express app) that uses a database service to allocate a status position for a Verifiable Credential, adds the position to the credential, and returns the credential. The status position can later be used to revoke the credential.
Implements two HTTP endpoints:
The /credentials/status
endpoint corresponds to the VC-API /credentials/status endpoint
This service provides support for managing credential status in a variety of database services. Currently, it supports integration with MongoDB via this implementation of Bitstring Status List. We have provided a sample .env.example
file that you can use as a guide for creating a .env
file for your implementation. Here are the variables recognized by all database credential status managers:
Key | Description | Type | Required |
---|---|---|---|
CRED_STATUS_SERVICE |
name of the database service used to manage credential status data | mongodb |
yes |
* STATUS_CRED_SITE_ORIGIN |
base URL of status credentials managed by a given deployment | string | yes |
CRED_STATUS_DB_URL |
URL of the database instance used to manage credential status data | string | yes if the other set of CRED_STATUS_DB_* fields are not set |
CRED_STATUS_DB_HOST |
host of the database instance used to manage credential status data | string | yes if CRED_STATUS_DB_URL is not set |
CRED_STATUS_DB_PORT |
port of the database instance used to manage credential status data | number | yes if CRED_STATUS_DB_URL is not set |
CRED_STATUS_DB_USER |
username of user with read/write privileges on the database instance used to manage credential status data | string | yes if CRED_STATUS_DB_URL is not set |
CRED_STATUS_DB_PASS |
password associated with CRED_STATUS_DB_USER |
string | yes if CRED_STATUS_DB_URL is not set |
CRED_STATUS_DB_NAME |
name of the database instance used to manage credential status data | string | no (default: credentialStatus ) |
STATUS_CRED_TABLE_NAME |
name of the database table used to manage status credentials | string | no (default: StatusCredential ) |
USER_CRED_TABLE_NAME |
name of the database table used to manage user credentials | string | no (default: UserCredential ) |
CONFIG_TABLE_NAME |
name of the database table used to manage application configuration | string | no (default: Config ) |
EVENT_TABLE_NAME |
name of the database table used to manage credential status events | string | no (default: Event ) |
CRED_EVENT_TABLE_NAME |
name of the database table used to manage the latest status event for a given credential | string | no (default: CredentialEvent ) |
CRED_STATUS_DID_SEED |
seed used to deterministically generate DID | string | yes |
PORT |
HTTP port on which to run the express app | number | no (default: 4008 ) |
ENABLE_ACCESS_LOGGING |
whether to enable access logging (see Logging) | boolean | no (default: true ) |
ENABLE_HTTPS_FOR_DEV |
whether to enable HTTPS in a development instance of the app | boolean | no (default: true ) |
ERROR_LOG_FILE |
log file for all errors (see Logging) | string | no |
ALL_LOG_FILE |
log file for everything (see Logging) | string | no |
CONSOLE_LOG_LEVEL |
console log level (see Logging) | error | warn | info | http | verbose | debug | silly |
no (default: silly ) |
LOG_LEVEL |
log level for application (see Logging) | error | warn | info | http | verbose | debug | silly |
no (default: silly ) |
* See Usage for guidance on setting a test value for STATUS_CRED_SITE_ORIGIN
.
status-service-db
is configured with a default signing key that can only be used for testing and evaluation.
In production, you must generate your own signing key and assign it to the CRED_STATUS_DID_SEED
environment variable. An easy-ish way to generate a new key is explained here. Those instructions will give you a JSON object with a seed
property. Copy the value of that property and assign it to CRED_STATUS_DID_SEED
.
So that a verifier knows that the status list was signed by a key that is really owned by the claimed issuer, the key (encoded as a DID) has to be confirmed as really belonging to that issuer. This is typically done by adding the DID to a well known registry that the verifier checks when verifying a credential.
The DCC provides a number of registries that work with the verifiers in the Learner Credential Wallet and in the online web based Verifier Plus. The DCC registries use GitHub for storage. To request that your DID be added to a registry, submit a pull request in which you've added your DID to the registry file.
The /credentials/status/allocate
HTTP endpoint is meant to be called from any software wanting to allocate a position, particularly by the DCC issuer-coordinator from within a Docker Compose network.
This express app can be run a few different ways:
- 1 with with the
start
script in package.json - 2 directly from the Docker Hub image:
docker run -dp 4008:4008 digitalcredentials/status-service-db:0.1.0
- 2 with Docker Compose - see how we do that in the DCC issuer-coordinator
1 In order for credential status verification to work, you will need to use a publicly accessible URL for STATUS_CRED_SITE_ORIGIN
, so that the verifier can access the status data. If you would like to spin up this service at a public URL, consider using a traffic forwarding tool like localtunnel. After you have installed it on your computer with npm install -g localtunnel
, please follow these simple steps to run the service:
- Run
npm run lt
(assuming you have already set thePORT
environment variable) - Visit the URL that is logged to the terminal and enter the tunnel password (typically your public IP address, which can be found at sites like ip.me)
- Set the
STATUS_CRED_SITE_ORIGIN
environment variable to the URL generated from Step 2 (be sure to also configure all other required environment variables) - Run
npm start
(assuming you have already runnpm install
)
2 Note that to run this with Docker, you'll of course need to install Docker, which is very easy with the Docker installers for Windows, Mac, and Linux.
You can now allocate status positions for Verifiable Credentials. Try it out with this cURL command, which you simply paste into the terminal:
curl --location 'http://localhost:4008/credentials/status/allocate' \
--header 'Content-Type: application/json' \
--data-raw '{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json"
],
"id": "urn:uuid:2fe53dc9-b2ec-4939-9b2c-0d00f6663b6c",
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
],
"name": "DCC Test Credential",
"issuer": {
"type": [
"Profile"
],
"id": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"name": "Digital Credentials Consortium Test Issuer",
"url": "https://dcconsortium.org",
"image": "https://user-images.githubusercontent.com/752326/230469660-8f80d264-eccf-4edd-8e50-ea634d407778.png"
},
"validFrom": "2023-08-02T17:43:32.903Z",
"credentialSubject": {
"type": [
"AchievementSubject"
],
"achievement": {
"id": "urn:uuid:bd6d9316-f7ae-4073-a1e5-2f7f5bd22922",
"type": [
"Achievement"
],
"achievementType": "Diploma",
"name": "Badge",
"description": "This is a sample credential issued by the Digital Credentials Consortium to demonstrate the functionality of Verifiable Credentials for wallets and verifiers.",
"criteria": {
"type": "Criteria",
"narrative": "This credential was issued to a student that demonstrated proficiency in the Python programming language that occurred from **February 17, 2023** to **June 12, 2023**."
},
"image": {
"id": "https://user-images.githubusercontent.com/752326/214947713-15826a3a-b5ac-4fba-8d4a-884b60cb7157.png",
"type": "Image"
}
},
"name": "Jane Doe"
}
}'
This should return the same credential but with an allocated status. It should look something like this (it will be all smushed up, but you can format it in something like JSONLint):
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json",
"https://w3id.org/security/suites/ed25519-2020/v1"
],
"id": "urn:uuid:2fe53dc9-b2ec-4939-9b2c-0d00f6663b6c",
"type": [
"VerifiableCredential",
"OpenBadgeCredential"
],
"name": "DCC Test Credential",
"issuer": {
"type": [
"Profile"
],
"id": "did:key:z6MknNQD1WHLGGraFi6zcbGevuAgkVfdyCdtZnQTGWVVvR5Q",
"name": "Digital Credentials Consortium Test Issuer",
"url": "https://dcconsortium.org",
"image": "https://user-images.githubusercontent.com/752326/230469660-8f80d264-eccf-4edd-8e50-ea634d407778.png"
},
"validFrom": "2023-08-02T17:43:32.903Z",
"credentialSubject": {
"type": [
"AchievementSubject"
],
"achievement": {
"id": "urn:uuid:bd6d9316-f7ae-4073-a1e5-2f7f5bd22922",
"type": [
"Achievement"
],
"achievementType": "Diploma",
"name": "Badge",
"description": "This is a sample credential issued by the Digital Credentials Consortium to demonstrate the functionality of Verifiable Credentials for wallets and verifiers.",
"criteria": {
"type": "Criteria",
"narrative": "This credential was issued to a student that demonstrated proficiency in the Python programming language that occurred from **February 17, 2023** to **June 12, 2023**."
},
"image": {
"id": "https://user-images.githubusercontent.com/752326/214947713-15826a3a-b5ac-4fba-8d4a-884b60cb7157.png",
"type": "Image"
}
},
"name": "Jane Doe"
},
"credentialStatus": [
{
"id": "https://digitalcredentials.github.io/credential-status-jc-test/XA5AAK1PV4#2",
"type": "BitstringStatusListEntry",
"statusPurpose": "revocation",
"statusListIndex": 2,
"statusListCredential": "https://digitalcredentials.github.io/credential-status-jc-test/XA5AAK1PV4"
},
{
"id": "https://digitalcredentials.github.io/credential-status-jc-test/DKSPRCX9WB#5",
"type": "BitstringStatusListEntry",
"statusPurpose": "suspension",
"statusListIndex": 5,
"statusListCredential": "https://digitalcredentials.github.io/credential-status-jc-test/DKSPRCX9WB"
}
]
}
Now, your next step would be to sign this Verifiable Credential. You could pass the VC (with its newly allocated status position) to the DCC signing-service, which will sign and return the signed copy. To see how this is can all be coordinated, take a look at the DCC issuer-coordinator.
NOTE: cURL can get a bit clunky if you want to experiment more (e.g., by changing what goes into the VC before signing), so you might consider trying Postman which makes it easier to construct and send HTTP calls.
Revocation and suspension are fully explained in the Bitstring Status List specification and our implemenations thereof, but effectively, it amounts to POSTing an object containing the credential ID and the desired status update to the /credentials/status
endpoint. For example:
curl --location 'http://localhost:4008/credentials/status' \
--header 'Content-Type: application/json' \
--data-raw '{
"credentialId": "urn:uuid:951b475e-b795-43bc-ba8f-a2d01efd2eb1",
"credentialStatus": [
{ "type": "BitstringStatusListCredential", "status": "revoked" }
]
}
status-service-db
is primarily intended to run as a Docker image within a Docker Compose network, typically as part of a flow that is orchestrated by the DCC Issuer Coordinator and the DCC Workflow Coordinator.
For convenience, we've published the images for the status-service-db
and the other services used by the coordinators, as well as for the coordinators themselves, to Docker Hub so that you don't have to build them locally yourself from the GitHub repositories.
The images on Docker Hub will at times be updated to add new functionality and fix bugs. Rather than overwrite the default (latest
) version on Docker Hub for each update, we've adopted the Semantic Versioning Guidelines with our Docker image tags.
We DO NOT provide a latest
tag so you must provide a tag name (i.e, the version number) for the images in your Docker Compose file.
To ensure you've got compatible versions of the services and the coordinator, the major
number for each should match. At the time of writing, the versions for each are at 0.1.0, and the major
number (the leftmost number) agrees across all three.
If you do ever want to work from the source code in the repository and build your own images, we've tagged the commits in GitHub that were used to build the corresponding Docker image. So a GitHub tag of v0.1.0 coresponds to a Docker image tag of 0.1.0
We support the following log levels:
error: 0,
warn: 1,
info: 2,
http: 3,
verbose: 4,
debug: 5,
silly: 6
Logging is configured with environment variables, as defined in the Environment Variables section.
By default, everything is logged to the console (log level silly
).
You may set the log level for the application as a whole. For example:
LOG_LEVEL=http
Which would only log messages with severity http
and all below it (info
, warn
, error
).
The default is to log everything (level silly
).
You can also set the log level for console logging. For example:
CONSOLE_LOG_LEVEL=debug
This would log everything for severity debug
and lower (i.e., verbose
, http
, info
, warn
, error
). This of course assumes that you've set the log level for the application as a whole to at least the same level.
The default log level for the console is silly
, which logs everything.
There are also two log files that can be enabled:
- errors (only logs errors)
- all (logs everything - all log levels)
Enable each log by setting an environment variable for each, indicating the path to the appropriate file, like this example:
ERROR_LOG_FILE=logs/error.log
ALL_LOG_FILE=logs/all.log
If you don't set the path, the log is disabled.
Finally, you can enable access logging to record each API request. Here is the format of each log entry:
:REMOTE_ADDRESS :HTTP_METHOD :URL :HTTP_STATUS :RESPONSE_CONTENT_LENGTH - :RESPONSE_TIME_MS
To enable access logging, set ENABLE_ACCESS_LOGGING
to true
.
Clone code then cd into directory and:
npm install
npm run dev
Testing uses mocha
and supertest
to test the endpoints. To run tests:
npm run test
Because status-service-db
uses database services to manage status, calls are made out to HTTP API endpoints during issuance. Rather than making these calls for every test, and possibly in cases where outgoing HTTP calls aren't ideal, we've mocked the @digitalcredentials/credential-status-manager-db
package.
PRs accepted.
If editing the Readme, please conform to the standard-readme specification.
MIT License © 2024 Digital Credentials Consortium.