generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
253 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# How To: Create a Credential | ||
|
||
## Background | ||
|
||
A [Verifiable Credential (VC)](https://www.w3.org/TR/vc-data-model/) is a standard format to package a set of claims that an _issuer_ makes about a _subject_. The Verifiable Credentials Data Model, a W3C standard, introduces a number of concepts, most notable among them, the [three party model](https://www.w3.org/TR/vc-data-model/#ecosystem-overview) of **issuers**, **holders**, and **verifiers**. The model is a novel way of empowering entities to have tamper-evident representations of their data which acts as a mechanism to present the data to any third party (a verifier) without necessitating contact between the verifier and issuer. With the three party model entities are given more [control, transparency, privacy, and utility](https://www.lifewithalacrity.com/2016/04/the-path-to-self-soverereign-identity.html) for data that is rightfully theirs. | ||
|
||
VCs are defined by a data model, which does not provide guidance on transmitting or sharing credentials between parties (protocols). The data model also does not provide guidance on _securing_ the credential (which puts the verifiable in verifiable credential). There are two prominent options here: [Data Integrity](https://www.w3.org/TR/vc-data-integrity/) and [JOSE/COSE](https://www.w3.org/TR/vc-jose-cose/) both of which we have demonstrated support for. The data model has a number of required (core) properties, and multiple means of extension to meet many use cases and functional needs. | ||
|
||
## VCs in the SSI Service | ||
|
||
VCs are a core component of SSI (Self Sovereign Identity) systems and work hand-in-hand with [DIDs](did.md). In our system, DIDs are used to represent the _issuer_ as well as the _subject_ of a credential. To define which content is in a VC we make use of [JSON schemas](schema.md). | ||
|
||
The SSI Service is transport-agnostic and does not mandate the usage of a single mechanism to deliver credentials to an intended holder. We have begun integration with both [Web5](https://github.com/TBD54566975/dwn-sdk-js#readme) and [OpenID Connect](https://openid.net/sg/openid4vc/) transportation mechanisms but leave the door open to any number of possibile options. | ||
|
||
At present, the service supports issuing credentials using the [v1.1 data model as a JWT](https://www.w3.org/TR/vc-data-model/#json-web-token). There is support for verifying credentials that make use of select [Data Integrity cryptographic suites](https://w3c.github.io/vc-data-integrity/) though use is discouraged due to complexity and potential security risks. Support for [v2.0](https://w3c.github.io/vc-data-model/) of the data model is planned and coming soon! | ||
|
||
Out of the box we have support for exposing two [credential statuses](status.md) using the [Verifiable Credentials Status List](https://w3c.github.io/vc-status-list-2021/) specification: suspension and revocation. | ||
|
||
## Creating a Verifiable Credential | ||
|
||
Creating a credential using the SSI Service currently requires four pieces of data: an `issuer` DID, a `verificationMethodId` which must be contained within the issuer's DID Document, a `subject` DID (the DID who the claims are about), and `data` which is an arbitrary JSON object for the claims that you wish to be in the credential (in the `credentialSubject` property). | ||
|
||
There are additional optional properties that let you specify `evidence`, an `expiry`, and whether you want to make the credential `revocable` or `suspendable`. Let's keep things simple and issue our first credential which will attest to a person's first and last name. | ||
|
||
### 1. Create an issuer DID | ||
|
||
We need two pieces of issuer information to create the credential: their DID and a verification method identifier. To get both, let's create a `did:key` to act as the issuer, with the following `PUT` command to `/v1/dids/key`. | ||
|
||
```bash | ||
curl -X PUT localhost:3000/v1/dids/key -d '{"keyType": "Ed25519"}' | ||
``` | ||
|
||
We get back a response with the `id` as `did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD`. Since we're using DID key we know that there is only a single key and its' `verificationMethodId` is the DID suffix: `did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD#z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD`. This value could be retrieved by resolving the DID or by making a `GET` request to `/v1/dids/key/did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD` as well. | ||
|
||
### 2. Create a person schema | ||
|
||
Because we want to include information about the subject in the credential, let's first create a schema to define the shape of the credential's data with required `firstName` and `lastName` values. While this step is optional, it's a good practice to have a schema that describes the shape of the data. | ||
|
||
Once we have our schema, we'll submit it to the service with a `PUT` request to `v1/schemas` as follows: | ||
|
||
```bash | ||
curl -X PUT localhost:3000/v1/schemas -d '{ | ||
"name": "Person Credential", | ||
"schema": { | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"type": "object", | ||
"properties": { | ||
"credentialSubject": { | ||
"type": "object", | ||
"properties": { | ||
"firstName": { | ||
"type": "string" | ||
}, | ||
"lastName": { | ||
"type": "string" | ||
} | ||
}, | ||
"required": ["firstName", "lastName"] | ||
} | ||
} | ||
} | ||
}' | ||
``` | ||
|
||
After submission we get back an identifier to refer to the schema as `aed6f4f0-5ed7-4d7a-a3df-56430e1b2a88`. | ||
|
||
### 3. Create a credential | ||
|
||
Separately, we've figured out that the subject we're creating the credential for has the DID `did:key:z6MkmNnvnfzW3nLiePweN3niGLnvp2BjKx3NM186vJ2yRg2z`. Now we have all the set up done we're ready to create our credential. | ||
|
||
Construct a `PUT` request to `/v1/credentials` as follows: | ||
|
||
```bash | ||
curl -X PUT localhost:3000/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" | ||
} | ||
}' | ||
``` | ||
|
||
Upon success we'll see a response such as: | ||
|
||
```json | ||
{ | ||
"id": "46bc3d25-6aaf-4f50-99ed-61c4b35f6411", | ||
"fullyQualifiedVerificationMethodId": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD#z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD", | ||
"credential": { | ||
"@context": ["https://www.w3.org/2018/credentials/v1"], | ||
"id": "http://localhost:3000/v1/credentials/46bc3d25-6aaf-4f50-99ed-61c4b35f6411", | ||
"type": ["VerifiableCredential"], | ||
"issuer": "did:key:z6Mkm1TmRWRPK6n21QncUZnk1tdYkje896mYCzhMfQ67assD", | ||
"issuanceDate": "2023-07-28T12:45:15-07:00", | ||
"credentialSubject": { | ||
"id": "did:key:z6MkmNnvnfzW3nLiePweN3niGLnvp2BjKx3NM186vJ2yRg2z", | ||
"firstName": "Satoshi", | ||
"lastName": "Nakamoto" | ||
}, | ||
"credentialSchema": { | ||
"id": "aed6f4f0-5ed7-4d7a-a3df-56430e1b2a88", | ||
"type": "JsonSchema2023" | ||
} | ||
}, | ||
"credentialJwt": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa20xVG1SV1JQSzZuMjFRbmNVWm5rMXRkWWtqZTg5Nm1ZQ3poTWZRNjdhc3NEI3o2TWttMVRtUldSUEs2bjIxUW5jVVpuazF0ZFlramU4OTZtWUN6aE1mUTY3YXNzRCIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTA1NzM1MTUsImlzcyI6ImRpZDprZXk6ejZNa20xVG1SV1JQSzZuMjFRbmNVWm5rMXRkWWtqZTg5Nm1ZQ3poTWZRNjdhc3NEIiwianRpIjoiaHR0cDovL2xvY2FsaG9zdDozMDAwL3YxL2NyZWRlbnRpYWxzLzQ2YmMzZDI1LTZhYWYtNGY1MC05OWVkLTYxYzRiMzVmNjQxMSIsIm5iZiI6MTY5MDU3MzUxNSwibm9uY2UiOiIzMGMwNDYxZi1jMWUxLTQwNDctYWUwYS01NjgzMjdkMzY4YTYiLCJzdWIiOiJkaWQ6a2V5Ono2TWttTm52bmZ6VzNuTGllUHdlTjNuaUdMbnZwMkJqS3gzTk0xODZ2SjJ5UmcyeiIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiZmlyc3ROYW1lIjoiU2F0b3NoaSIsImxhc3ROYW1lIjoiTmFrYW1vdG8ifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6ImFlZDZmNGYwLTVlZDctNGQ3YS1hM2RmLTU2NDMwZTFiMmE4OCIsInR5cGUiOiJKc29uU2NoZW1hMjAyMyJ9fX0.xwqpDuO6PDeEqYr6DflbeR6mhuwvVg0uR43i-7Zhy2DdaH1e3Jt4DuiMy09tZQ2jAXki0rjMNgLt7dPpzOl8BA" | ||
} | ||
``` | ||
|
||
In the `credential` property we see an unsecured, but readable, version of the VC. The VC is signed and packaged as a JWT in the `credentialJwt` property. If you're interested, you can decode the JWT using a tool such as [jwt.io](https://jwt.io/). If you were to 'issue' or transmit the credential to a _holder_ you would just send this JWT value. | ||
|
||
## Getting Credentials | ||
|
||
Once you've created multiple credentials, you can view all credentials by making a `GET` request to `/v1/credentials`. This endpoint also supports three query parameters: `issuer`, `schema`, and `subject` which can be used mutually exclusively. | ||
|
||
You can get a single credential by making a `GET` request to `/v1/credentials/{id}`. | ||
|
||
## Other Credential Operations | ||
|
||
To learn about verifying credentials [read more here](verification.md). You can also learn more about [credential status here](status.md). | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# How To: Create a Schema | ||
|
||
## Background | ||
|
||
When creating [Verifiable Credentials](https://www.w3.org/TR/vc-data-model) it's useful to have a mechanism to define the shape the data in the credential takes, in a consistent manner. The VC Data Model uses an open world data model, and with it, provides a mechanism to "extend" the core terminology to add any term with a technology known as [JSON-LD](https://json-ld.org/). JSON-LD is responsible for the `@context` property visible in VCs, DIDs, and other documents in the SSI space. However, JSON-LD is focused on _semantics_, answering the question "do we have a shared understanding of what this thing is?" more specifically, for a name credential, does your concept of "name" match mine. Though the core data model is a JSON-LD data model, processing VCs as JSON-LD is not a requirement. The SSI Service chooses to take a simpler approach and [process VCs as pure JSON](https://www.w3.org/TR/vc-data-model/#json). | ||
|
||
When constructing and processing VCs as pure JSON it is useful to have a mechanism to define the data and add some light validation onto the shape that data takes. [JSON Schema](https://json-schema.org/) is a widely used, and widely supported toolset that enables such functionalty: the ability to define a schema, which provides a set of properties (both required and optional), and some light validation on top of those properties. The VC Data Model has [a section on data schemas](https://www.w3.org/TR/vc-data-model/#data-schemas) that enables this functionality. | ||
|
||
## Intro to JSON Schema with Verifiable Credentials | ||
|
||
Making use of the `credentialSchema` property [defined in the VC Data Model](https://www.w3.org/TR/vc-data-model/#data-schemas) TBD and other collaborators in the W3C are working on [a new specification](https://w3c.github.io/vc-json-schema/) which enables a standards-compliant path to using JSON Schema with Verifiable Credentials. The VC JSON Schema specification defines two options for using JSON Schemas: the first, a plan JSON Schema that can apply to _any set of properties_ in a VC, and the second, a Verifiable Credential that wraps a JSON Schema. | ||
|
||
In some cases it is useful to package a JSON Schema as a Verifiable Credential to retain information about authorship (who created the schema), when it was created, and enable other features the VC Data Model offers, such as the ability to suspend the usage of a schema with [a status](https://www.w3.org/TR/vc-data-model/#status). | ||
|
||
An example email JSON Schema using [JSON Schema Draft 2020-12](https://json-schema.org/draft/2020-12/json-schema-core.html) is provided below: | ||
|
||
```json | ||
{ | ||
"$id": "https://example.com/schemas/email.json", | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"name": "Email Address", | ||
"type": "object", | ||
"properties": { | ||
"emailAddress": { | ||
"type": "string", | ||
"format": "email" | ||
} | ||
}, | ||
"required": ["emailAddress"] | ||
} | ||
``` | ||
|
||
We can see that the schema defines a property `emailAddress` of JSON type `string`, and it is required. This means that any piece of JSON we apply this schema to will pass if a valid `emailAddress` property is present and fail otherwise. | ||
|
||
Now that we have a valid JSON Schema, we'll need to transform it so it's useful in being applied to a Verifiable Credential, not just any arbitrary JSON. We know that we want the presence of an `emailAddress` in the `credentialSubject` property of a VC and adjust the schema accordingly: | ||
|
||
```json | ||
{ | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"name": "Email Credential", | ||
"type": "object", | ||
"properties": { | ||
"credentialSubject": { | ||
"type": "object", | ||
"properties": { | ||
"emailAddress": { | ||
"type": "string", | ||
"format": "email" | ||
} | ||
}, | ||
"required": ["emailAddress"] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
Now our schema, applied to a Verifiable Credential, will guarantee that the `credentialSubject` property contains a valid `emailAddress` property. | ||
|
||
## Creating a Schema | ||
|
||
The service exposes a set of APIs for managing schemas. To create a schema you have two options: signed or not. As mentioned earlier, the signed version of a schema is packaged as a Verifiable Credential. To create a signed schema you'll need to pass in two additional properties – the issuer DID and the ID of the verification method to use to sign the schema. We'll keep things simple for now and create an unsigned schema. | ||
|
||
After forming a valid JSON Schema, generate a `PUT` request to `/v1/schemas` as follows: | ||
|
||
```bash | ||
curl -X PUT localhost:3000/v1/schemas -d '{ | ||
"name": "Email Credential", | ||
"schema": { | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"type": "object", | ||
"properties": { | ||
"credentialSubject": { | ||
"type": "object", | ||
"properties": { | ||
"emailAddress": { | ||
"type": "string", | ||
"format": "email" | ||
} | ||
}, | ||
"required": ["emailAddress"] | ||
} | ||
} | ||
} | ||
}' | ||
``` | ||
|
||
Upon success you'll see a response which includes the schema you passed in, with a service-generated identifier for the schema. You'll also notice a type `JsonSchema2023`, which is defined by the [VC JSON Schema specification](https://w3c.github.io/vc-json-schema/#jsonschema2023): | ||
|
||
```json | ||
{ | ||
"id": "ebeebf7b-d452-4832-b8d3-0042ec80e108", | ||
"type": "JsonSchema2023", | ||
"schema": { | ||
"$id": "http://localhost:3000/v1/schemas/ebeebf7b-d452-4832-b8d3-0042ec80e108", | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"name": "Email Credential", | ||
"properties": { | ||
"credentialSubject": { | ||
"properties": { | ||
"emailAddress": { | ||
"format": "email", | ||
"type": "string" | ||
} | ||
}, | ||
"required": [ | ||
"emailAddress" | ||
], | ||
"type": "object" | ||
} | ||
}, | ||
"type": "object" | ||
} | ||
} | ||
``` | ||
|
||
Now you're ready to use the schema in [creating a credential](credential.md). | ||
|
||
## Getting Schemas | ||
|
||
Once you've created multiple schemas, you can view them all by make a `GET` request to the `v1/schemas` endpoint. Future enhancements may enable filtering based on name, author, or other properties. | ||
|
||
You can get a specific schema by make a `GET` request to the `v1/schemas/{schemaId}` endpoint. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters