This is an example shell script using all the core functions of DIDKit-CLI: key generation, credential/presentation issuance and verification.
Setup
Note: This script is meant to be run in the directory where DIDKit-CLI is built, regardless of installation method. See the complete script below for setup details.
These instructions assume Ubuntu, and have been tested on Linux, MacOS, and WSL2.
See DIDKit installation page instructions for dependencies and install options.
jq is recommended but not required for testing purposes. It can be installed by running the command sudo apt-get install jq.
Start with a keypair
DIDKit can generate a unique ed25119 keypair from entropy. Alternately, you can provide a static key locally.
if [ -e issuer_key.jwk ]; thenecho'Using existing keypair.'elsedidkitgenerate-ed25519-key>issuer_key.jwkecho'Generated keypair.'fiecho
Generate a DID:Key document
This document gets wrapped around the keypair generated (or passed) in the previous step. For more context on the DID:key method, see the specification. For more info on the parameters and flags for the key-to-did function, run didkit help key-to-did.
This is used to identify the key in linked data proofs. Verifiers of such proofs query a DID found in a credential based on what [registered] proof type (i.e., what kind of signatures) it needs key material to verify.
Here, we'll issue an example credential (unsigned) and save it to a file. In this credential, the issuance date, id, and credential subject id are arbitrary, but in real-world usage these are diverse and critical properties. For more info about what these properties mean, see the Verifiable Credentials Data Model specification.
Note that SUBJECTDID and ISSUERDID fields need to be URIs, so if you are using non-DID identifiers such as certificates or UUIDs, they need to be prefixed with the appropriate URN prefix, i.e., "urn:uuid:", etc.
When working in a MacOS terminal, use the following command to format an ISO-8601 compliant date instead:
DATE=`date-u+"%Y-%m-%dT%H:%M:%SZ"`
Issue the verifiable credential
We ask DIDKit to issue a verifiable credential using the given keypair file, verification method, and proof purpose, passing the unsigned credential on standard input.
DIDKit creates a linked data proof to add to the unsigned credential, and outputs the resulting newly-issued (signed) verifiable credential on standard output, which we save to a file.
We pass the newly-issued signed verifiable credential back to didkit for verification using the given verification method and proof purpose.
DIDKit then outputs the verification result as JSON and saves it. If verification is successful, the command completes successfully (returns exit code 0).
if!didkitvc-verify-credential \-v"$issuer_verification_method" \-passertionMethod \<credential-signed.jsonld \>credential-verify-result.jsonthenecho'Unable to verify credential:'print_jsoncredential-verify-result.jsonexit1fiecho'Verified verifiable credential:'catcredential-verify-result.json|jq.
Create a verifiable presentation that embeds the verifiable credential
Prepare to present the verifiable credential by wrapping it in a verifiable presentation (VP).
The id here is an arbitrary URL for example purposes; VPs are often but not always uniquely identified, whether by identifiers, URLs, or URIs.
Pass the unsigned verifiable presentation to DIDKit to be issued as a verifiable presentation. * DIDKit signs the presentation with a linked data proof, using the given keypair, verification method and proof type.
We save the resulting newly created verifiable presentation to a file
In most use-cases, the holder field contains a DID or other identifier verifiably linked to the key material signing the presentation, which has some relationship to the credential(s) being presented.
The classic example is a fresh and interactive proof of being the [human] subject identified by a credential, but there are many VP use-cases as well. This may be a manual, consented, unique and interactive identity assurance operation, but it can also be an assurance of the identity of a machine or a legal entity, operated by an API call or an automation carried out by a fiduciary/trusted piece of software, etc.
In these examples, the keys representing the two parties are stored in expressive filenames, 'issuer_key' and 'holder_key'. There are, however, no differences between these keys, and the JWK filenames were chosen simply to clarify the example; there are no restrictions on them.
if!didkitvc-verify-presentation \-v"$issuer_verification_method" \-pauthentication \<presentation-signed.jsonld \>presentation-verify-result.jsonthenecho'Unable to verify presentation:'print_jsonpresentation-verify-result.jsonexit1fiecho'Verified verifiable presentation:'catpresentation-verify-result.json|jq.echoDone
Appendix: whole script without commentary
The following is a stand-alone version of all of the above, also available on Github as /cli/tests/example.sh
#!/bin/sh# This is an example shell script using DIDKit for key generation,# credential/presentation issuance and verification.# Exit if any command in the script fails.set-e# Allow issuing using a DID method other than did:keydid_method=${DID_METHOD:-key}# More info about did:key: https://w3c-ccg.github.io/did-method-key/# Allow setting proof format using environmental variables.proof_format=${PROOF_FORMAT:-ldp}vc_proof_format=${VC_PROOF_FORMAT:-$proof_format}vp_proof_format=${VP_PROOF_FORMAT:-$proof_format}# Pretty-print JSON using jq or json_pp if available.print_json() { file=${1?file}ifcommand-vjq>/dev/null2>&1; thenjq."$file"||cat"$file"elifcommand-vjson_pp>/dev/null2>&1; thenjson_pp<"$file"||cat"$file"elsecat"$file"fi}# Run the rest of this script in its source directory.cd"$(dirname "$0")"# Build the didkit CLI programcargobuild-pdidkit-cli# Adjust $PATH to include the didkit executable.export PATH="$PWD/../../target/debug:$PATH"# Create a ed25119 keypair if needed.if [ -e key.jwk ]; thenecho'Using existing keypair.'elsedidkitgenerate-ed25519-key>key.jwkecho'Generated keypair.'fiecho# Get the keypair's DID.did=$(didkitkey-to-did"$did_method"-kkey.jwk)printf'DID: %s\n\n'"$did"# Get verificationMethod for keypair.# This is used to identify the key in linked data proofs.verification_method=$(didkitkey-to-verification-method"$did_method"-kkey.jwk)printf'verificationMethod: %s\n\n'"$verification_method"# Prepare credential for issuing.# In this example credential, the issuance date, id, and credential subject id# are arbitrary. For more info about what these properties mean, see the# Verifiable Credentials Data Model: https://w3c.github.io/vc-data-model/cat>credential-unsigned.jsonld<<EOF{ "@context": "https://www.w3.org/2018/credentials/v1", "id": "http://example.org/credentials/3731", "type": ["VerifiableCredential"], "issuer": "$did", "issuanceDate": "2020-08-19T21:41:50Z", "credentialSubject": { "id": "did:example:d23dd687a7dc6787646f2eb98d0" }}EOF# Issue the verifiable credential.# Ask didkit to issue a verifiable credential using the given keypair file,# verification method, and proof purpose, passing the unsigned credential on# standard input. DIDKit creates a linked data proof to add to the credential,# and outputs the resulting newly-issued verifiable credential on standard# output, which we save to a file.didkitvc-issue-credential \-kkey.jwk \-v"$verification_method" \-passertionMethod \-f"$vc_proof_format" \<credential-unsigned.jsonld \>credential-signedecho'Issued verifiable credential:'if [ "$vc_proof_format"= jwt ]; thencatcredential-signedelseprint_jsoncredential-signedfiecho# Verify verifiable credential.# We pass the newly-issued verifiable credential back to didkit for# verification using the given verification method and proof purpose. DIDKit# outputs the verification result as JSON. If verification is successful, the# command completes successfully (returns exit code 0).if!didkitvc-verify-credential \-v"$verification_method" \-passertionMethod \-f"$vc_proof_format" \<credential-signed \>credential-verify-result.jsonthenecho'Unable to verify credential:'print_jsoncredential-verify-result.jsonexit1fiecho'Verified verifiable credential:'print_jsoncredential-verify-result.jsonecho# Encode credential as JSON for presenting.if [ "$vc_proof_format"= jwt ]; thenecho-n'"'catcredential-signedecho-n'"'elsecatcredential-signedfi> credential-signed.json# Create presentation embedding verifiable credential.# Prepare to present the verifiable credential by wrapping it in a# Verifiable Presentation. The id here is an arbitrary URL for example purposes.cat>presentation-unsigned.jsonld<<EOF{ "@context": ["https://www.w3.org/2018/credentials/v1"], "id": "http://example.org/presentations/3731", "type": ["VerifiablePresentation"], "holder": "$did", "verifiableCredential": $(cat credential-signed.json)}EOF# Issue verifiable presentation.# Pass the unsigned verifiable presentation to didkit to be issued as a# verifiable presentation. DIDKit signs the presentation with a linked data# proof, using the given keypair, verification method and proof type. We save# the resulting newly created verifiable presentation to a file.didkitvc-issue-presentation \-kkey.jwk \-v"$verification_method" \-pauthentication \-f"$vp_proof_format" \<presentation-unsigned.jsonld \>presentation-signedecho'Issued verifiable presentation:'if [ "$vp_proof_format"= jwt ]; thencatpresentation-signedelseprint_jsonpresentation-signedfiecho# Verify verifiable presentation.# Pass the verifiable presentation back to didkit for verification.# Examine the verification result JSON.if!didkitvc-verify-presentation \-v"$verification_method" \-pauthentication \-f"$vp_proof_format" \<presentation-signed \>presentation-verify-result.jsonthenecho'Unable to verify presentation:'print_jsonpresentation-verify-result.jsonexit1fiecho'Verified verifiable presentation:'print_jsonpresentation-verify-result.jsonecho# Resolve a DID.if!didkitdid-resolve"$did">did.jsonthenecho'Unable to resolve DID.'exit1fiecho'Resolved DID to DID document:'print_jsondid.json# Dereference a DID URLif!didkitdid-dereference"$verification_method">vm.jsonthenecho'Unable to dereference DID URL.'exit1fiecho'Dereferenced DID URL for verification method:'print_jsonvm.json# Authenticate with a DIDif! challenge=$(awk'BEGIN { srand(); print rand() }')thenecho'Unable to create challenge.'exit1fiif!didkitdid-auth \-kkey.jwk \-h"$did" \-pauthentication \-C"$challenge" \-v"$verification_method" \-f"$vp_proof_format" \>auththenecho'Unable to create DIDAuth response'exit1fiecho'Generated DIDAuth verifiable presentation:'if [ "$vp_proof_format"= jwt ]; thencatauthelseprint_jsonauthfiecho# Verify DID authif!didkitvc-verify-presentation \-pauthentication \-C"$challenge" \-f"$vp_proof_format" \<auth \>auth-verify-result.jsonthenecho'Unable to verify DIDAuth presentation:'print_jsonauth-verify-result.jsonexit1fiecho'Verified DIDAuth verifiable presentation:'print_jsonauth-verify-result.jsonecho# Convert VP to Canonicalized RDFif [ "$vp_proof_format"= ldp ]; thenif!didkitto-rdf-urdna2015<auth>auth.nqthenecho'Unable to convert/canonicalize document:'>&2exit1fiecho'Converted verifiable presentation to canonicalized N-Quads:'catauth.nqfiechoechoDone