Skip to content

digitalcredentials/status-service-git

Repository files navigation

Digital Credentials Consortium Status Service

Build status

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:0.1.0 then you'll want to use the corresponding tagged repo: https://github.com/digitalcredentials/status-service/tree/v0.1.0.

Table of Contents

Summary

A microservice (running as a nodejs express app) that allocates a revocation 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

Environment Variables

There is a sample .env file provided called .env.example to help you get started with your own .env file. The supported fields:

Key Description Default Required
PORT http port on which to run the express app 4008 no
CRED_STATUS_OWNER name of the owner account (personal or organization) in the source control service that will host the credential status resources no yes if ENABLE_STATUS_ALLOCATION is true
CRED_STATUS_REPO_NAME name of the credential status repository no yes if ENABLE_STATUS_ALLOCATION is true
CRED_STATUS_META_REPO_NAME name of the credential status metadata repository no yes if ENABLE_STATUS_ALLOCATION is true
CRED_STATUS_ACCESS_TOKEN Github access token for the credential status repositories no yes if ENABLE_STATUS_ALLOCATION is true
CRED_STATUS_DID_SEED seed used to deterministically generate DID no yes if ENABLE_STATUS_ALLOCATION is true
ERROR_LOG_FILE log file for all errors - see Logging no no
LOG_ALL_FILE log file for everything - see Logging no no
CONSOLE_LOG_LEVEL console log level - see Logging silly no
LOG_LEVEL log level for application - see Logging silly no

Github Repositories

You'll have to create two new github repositories that will be used exclusively to manage the status. Full details of the implementation are here

IMPORTANT NOTE The underlying status-list-manager-git package has slightly different configuration options, as described in its own readme. In particular it allows for using two separate github tokens for each of the status repo and the metadata repo, whereas this service only allows using a single token for both repositories. If you have a use case that requires separate tokens, please let us know, or better yet, submit a PR.

Similarly, we've only exposed the github options on the service, but if you would like to use gitlab instead, just let us know and we can expose those options.

Signing key

The status-service 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.

DID Registries

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.

Usage

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:

  • with with the start script in package.json
  • directly from the DockerHub image: docker run -dp 4008:4008 digitalcredentials/status-service:0.1.0
  • with docker compose - see how we do that in the DCC issuer-coordinator

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.

Allocate Status Position

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/2018/credentials/v1",
    "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"
  },
  "issuanceDate": "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 json lint:

{
    "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.2.json",
        "https://w3id.org/vc/status-list/2021/v1",
        "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"
    },
    "issuanceDate": "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://jchartrand.github.io/status-test-three/DKSPRCX9WB#5",
        "type": "StatusList2021Entry",
        "statusPurpose": "revocation",
        "statusListIndex": 5,
        "statusListCredential": "https://jchartrand.github.io/status-test-three/DKSPRCX9WB"
    }
}

Now your next step would be to sign this Verifiable Credential. You could, for example, 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 (like say 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.

Revoke

Revocation is fully explained in the StatusList2021 specifivation and the git status repo implemenation but amounts to POSTing an object to the revocation endpoint, like so:

{credentialId: '23kdr', credentialStatus: [{type: 'StatusList2021Credential', status: 'revoked'}]}

Fundamentally, you are just posting up the id of the credential.

Versioning

The status-service 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 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 of course 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

Logging

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 whole, e.g.,

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, e.g.,

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 env variable for each, indicating the path to the appropriate file, like this example:

LOG_ALL_FILE=logs/all.log
ERROR_LOG_FILE=logs/error.log

If you don't set the path, the log is disabled.

Development

Installation

Clone code then cd into directory and:

npm install
npm run dev

Testing

Testing uses supertest, jest, and nock to test the endpoints. To run tests:

npm run test

Because the revocation (status) system uses github to store status, calls are made out to github during issuance. Rather than have to make these calls for every test, and possibly in cases where outgoing http calls aren't ideal, we've used mocked the @digitalcredentials/credential-status-manager-git package.

Contribute

PRs accepted.

If editing the Readme, please conform to the standard-readme specification.

License

MIT License © 2023 Digital Credentials Consortium.