-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feat/enveloping_proof' of github.com:uncefact/project-v…
…ckit into feat/enveloping_proof
- Loading branch information
Showing
17 changed files
with
1,734 additions
and
0 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
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,190 @@ | ||
# Credential Data Integrity Plugin | ||
|
||
This plugin draws inspiration from [eddsa-rdfc-2022-cryptosuite](@digitalbazaar/eddsa-rdfc-2022-cryptosuite) and is implemented as a plugin for [Veramo](https://veramo.io/). It adheres to the [Data Integrity EdDSA Cryptosuites v1.0](https://www.w3.org/TR/vc-di-eddsa/) specification to generate a Credential Data Integrity for credentials. | ||
|
||
This plugin contains a message handler for issuing and verifying credentials that adhere to W3C standards. | ||
|
||
## Current state | ||
|
||
This plugin is in the early stages of development and is not yet ready for production use. It is not recommended to use this plugin in a production environment. | ||
|
||
Currently, this plugin cannot be used alongside other plugins due to limitations in the Veramo core plugins. We plan to update the plugin in the future to enable compatibility with other plugins. | ||
|
||
## Setup | ||
|
||
If you want to try using the Credential Data Integrity plugin with a `did:web` DID, you can use the following example to create a Web DID Document router. | ||
|
||
- Create a Web DID Document router. You can use the following docs: [Set up Web DID Document Router](./web-did-doc-router-example.md) | ||
|
||
- Declare the plugin in your Veramo [agent](../../agent.yml): | ||
|
||
```yaml | ||
credentialIssuerLD: | ||
$require: '@veramo/credential-ld#CredentialIssuerLD' | ||
$args: | ||
- suites: | ||
- $require: '@vckit/credential-data-integrity#VCkitEddsaRdfc2022' | ||
# others should be included here | ||
contextMaps: | ||
- $require: '@vckit/credential-data-integrity?t=object#contexts' | ||
# others should be included here | ||
``` | ||
|
||
## Issue the Credential example | ||
|
||
You can issue a new verifiable credential by using the `/agent/routeCreationVerifiableCredential` API endpoint with the proof format set to `lds`. The issuer can be a `did:web`. | ||
|
||
The example below shows how to issue a credential with the Data Integrity Integrity plugin. You can replace the `issuer` and `credentialSubject` with your own data. | ||
|
||
### Verifiable Credential Data Model V1 | ||
|
||
```curl | ||
curl --request POST \ | ||
--url http://localhost:3332/agent/routeCreationVerifiableCredential \ | ||
--header 'Content-Type: application/json' \ | ||
--data '{ | ||
"credential": { | ||
"@context": [ | ||
"https://www.w3.org/2018/credentials/v1", | ||
"https://w3id.org/security/multikey/v1", | ||
"https://w3id.org/security/data-integrity/v2" | ||
], | ||
"type": [ | ||
"VerifiableCredential" | ||
], | ||
"issuer": "did:web:example.com", | ||
"issuanceDate": "2021-01-01T19:23:24Z", | ||
"credentialSubject": { | ||
"id": "did:example:456", | ||
"name": "John Doe" | ||
} | ||
}, | ||
"proofFormat": "lds", | ||
"save": true, | ||
"fetchRemoteContexts": true | ||
}' | ||
``` | ||
|
||
### Verifiable credential data model V2 | ||
|
||
```curl | ||
curl --request POST \ | ||
--url http://localhost:3332/agent/routeCreationVerifiableCredential \ | ||
--header 'Content-Type: application/json' \ | ||
--data '{ | ||
"credential": { | ||
"@context": [ | ||
"https://www.w3.org/ns/credentials/v2", | ||
"https://w3id.org/security/multikey/v1", | ||
"https://w3id.org/security/data-integrity/v2" | ||
], | ||
"id": "http://university.example/credentials/1872", | ||
"type": [ | ||
"VerifiableCredential", | ||
"ExampleAlumniCredential" | ||
], | ||
"issuer": "did:web:example.com", | ||
"validFrom": "2010-01-01T19:23:24Z", | ||
"credentialSchema": { | ||
"id": "https://example.org/examples/degree.json", | ||
"type": "JsonSchema" | ||
}, | ||
"credentialSubject": { | ||
"id": "did:example:123", | ||
"degree": { | ||
"type": "BachelorDegree", | ||
"name": "Bachelor of Science and Arts" | ||
} | ||
} | ||
}, | ||
"proofFormat": "lds", | ||
"save": true, | ||
"fetchRemoteContexts": true | ||
}' | ||
``` | ||
|
||
## Verify the credential example | ||
|
||
You can verify the verifiable credential by using the `/agent/routeVerificationCredential` API endpoint. | ||
|
||
The examples below show how to verify the verifiable credentials in the examples above using the Data Integrity proof. | ||
|
||
### Verifiable Credential Data Model V1 | ||
|
||
```curl | ||
curl --request POST \ | ||
--url http://localhost:3332/agent/routeVerificationCredential \ | ||
--header 'Content-Type: application/json' \ | ||
--data '{ | ||
"credential": { | ||
"@context": [ | ||
"https://www.w3.org/2018/credentials/v1", | ||
"https://w3id.org/security/multikey/v1", | ||
"https://w3id.org/security/data-integrity/v2" | ||
], | ||
"type": [ | ||
"VerifiableCredential" | ||
], | ||
"issuer": "did:web:example.com", | ||
"issuanceDate": "2021-01-01T19:23:24Z", | ||
"credentialSubject": { | ||
"id": "did:example:456", | ||
"name": "John Doe" | ||
}, | ||
"proof": { | ||
"type": "DataIntegrityProof", | ||
"created": "2024-07-21T15:39:40Z", | ||
"verificationMethod": "did:web:example.com#14fe3440c6d669edd8a63dc92b571fb0973fd4b832444014e69bcf8cebd38853", | ||
"cryptosuite": "eddsa-rdfc-2022", | ||
"proofPurpose": "assertionMethod", | ||
"proofValue": "z2S6qW6k6M6eXuqGkX5vdydqveSNVBSZf46MxxjY5ukv8gL741pos3yywT9mGTjKJzdjxQvaCSSVtCAngoAWQzNnq" | ||
} | ||
}, | ||
"fetchRemoteContexts": true | ||
}' | ||
``` | ||
|
||
### Verifiable Credential Data Model V2 | ||
|
||
```curl | ||
curl --request POST \ | ||
--url http://localhost:3332/agent/routeVerificationCredential \ | ||
--header 'Content-Type: application/json' \ | ||
--data '{ | ||
"credential": { | ||
"@context": [ | ||
"https://www.w3.org/ns/credentials/v2", | ||
"https://w3id.org/security/multikey/v1", | ||
"https://w3id.org/security/data-integrity/v2" | ||
], | ||
"id": "http://university.example/credentials/1872", | ||
"type": [ | ||
"VerifiableCredential", | ||
"ExampleAlumniCredential" | ||
], | ||
"issuer": "did:web:example.com", | ||
"validFrom": "2010-01-01T19:23:24Z", | ||
"credentialSchema": { | ||
"id": "https://example.org/examples/degree.json", | ||
"type": "JsonSchema" | ||
}, | ||
"credentialSubject": { | ||
"id": "did:example:123", | ||
"degree": { | ||
"type": "BachelorDegree", | ||
"name": "Bachelor of Science and Arts" | ||
} | ||
}, | ||
"issuanceDate": "2024-07-25T09:25:22.788Z", | ||
"proof": { | ||
"type": "DataIntegrityProof", | ||
"created": "2024-07-25T09:25:23Z", | ||
"verificationMethod": "did:web:example.com#a0b90e4ec2c9fbc63c50f230b98ea8335af1da5bba9472684519ae7da11273d6", | ||
"cryptosuite": "eddsa-rdfc-2022", | ||
"proofPurpose": "assertionMethod", | ||
"proofValue": "zbS3i4uaUzAw1J7Eb544Tgqfo8azhJkx3jGS5wtk4WCBe2CkAZyLEnX7Au7n3anEtTWaG9f283NF2rzJEsxFKjPE" | ||
} | ||
}, | ||
"fetchRemoteContexts": true | ||
}' | ||
``` |
51 changes: 51 additions & 0 deletions
51
packages/credential-data-integrity/__tests__/default-contexts.test.ts
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,51 @@ | ||
import { contexts } from '../src'; | ||
import contextCredentialV1 from '../src/contexts/www.w3.org_2018_credentials_v1.json'; | ||
import contextCredentialV2 from '../src/contexts/www.w3.org_ns_credentials_v2.json'; | ||
import contextDidV1 from '../src/contexts/www.w3.org_ns_did_v1.json'; | ||
import contextMultikey from '../src/contexts/w3id.org_security_multikey_v1.json'; | ||
import contextDataIntegrityV1 from '../src/contexts/w3id.org_security_data-integrity_v1.json'; | ||
import contextDataIntegrityV2 from '../src/contexts/w3id.org_security_data-integrity_v2.json'; | ||
|
||
describe('Contexts Map', () => { | ||
// Test to verify that the map contains exactly six contexts | ||
test('should contain the correct number of contexts', () => { | ||
// Check if the size of the map is 6 | ||
expect(contexts.size).toBe(6); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://www.w3.org/2018/credentials/v1' | ||
test('should map "https://www.w3.org/2018/credentials/v1" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://www.w3.org/2018/credentials/v1')).toBe(contextCredentialV1); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://www.w3.org/ns/credentials/v2' | ||
test('should map "https://www.w3.org/ns/credentials/v2" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://www.w3.org/ns/credentials/v2')).toBe(contextCredentialV2); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://www.w3.org/ns/did/v1' | ||
test('should map "https://www.w3.org/ns/did/v1" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://www.w3.org/ns/did/v1')).toBe(contextDidV1); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://w3id.org/security/multikey/v1' | ||
test('should map "https://w3id.org/security/multikey/v1" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://w3id.org/security/multikey/v1')).toBe(contextMultikey); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://w3id.org/security/data-integrity/v1' | ||
test('should map "https://w3id.org/security/data-integrity/v1" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://w3id.org/security/data-integrity/v1')).toBe(contextDataIntegrityV1); | ||
}); | ||
|
||
// Test to verify the mapping for 'https://w3id.org/security/data-integrity/v2' | ||
test('should map "https://w3id.org/security/data-integrity/v2" to the correct context', () => { | ||
// Check if the map returns the correct JSON object for the given URL | ||
expect(contexts.get('https://w3id.org/security/data-integrity/v2')).toBe(contextDataIntegrityV2); | ||
}); | ||
}); |
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,18 @@ | ||
{ | ||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", | ||
"apiReport": { | ||
"enabled": true, | ||
"reportFolder": "./api", | ||
"reportTempFolder": "./api" | ||
}, | ||
|
||
"docModel": { | ||
"enabled": true, | ||
"apiJsonFilePath": "./api/<unscopedPackageName>.api.json" | ||
}, | ||
|
||
"dtsRollup": { | ||
"enabled": false | ||
}, | ||
"mainEntryPointFilePath": "<projectFolder>/build/index.d.ts" | ||
} |
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,44 @@ | ||
{ | ||
"name": "@vckit/credential-data-integrity", | ||
"description": "Veramo plugin for working with W3C JSON-LD Verifiable Credentials.", | ||
"version": "1.0.0", | ||
"type": "module", | ||
"main": "build/index.js", | ||
"exports": { | ||
".": "./build/index.js" | ||
}, | ||
"types": "build/index.d.ts", | ||
"scripts": { | ||
"build": "tsc" | ||
}, | ||
"dependencies": { | ||
"@digitalbazaar/data-integrity": "^2.1.0", | ||
"@digitalbazaar/ed25519-multikey": "^1.1.0", | ||
"@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.0.1", | ||
"@vckit/core-types": "workspace:*", | ||
"@veramo/utils": "5.5.3", | ||
"@veramo/credential-ld": "link:../../.tmp_npm/veramo/packages/credential-ld" | ||
}, | ||
"devDependencies": { | ||
"typescript": "5.3.3" | ||
}, | ||
"files": [ | ||
"build/**/*", | ||
"src/**/*", | ||
"contexts/**/*.json", | ||
"README.md" | ||
], | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"keywords": [ | ||
"Veramo", | ||
"DID", | ||
"Verifiable Credential", | ||
"JSON-LD", | ||
"Data Integrity", | ||
"MultiKey", | ||
"vc-ld-json", | ||
"veramo-plugin" | ||
] | ||
} |
78 changes: 78 additions & 0 deletions
78
packages/credential-data-integrity/src/contexts/w3id.org_security_data-integrity_v1.json
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,78 @@ | ||
{ | ||
"@context": { | ||
"id": "@id", | ||
"type": "@type", | ||
"@protected": true, | ||
"digestMultibase": { | ||
"@id": "https://w3id.org/security#digestMultibase", | ||
"@type": "https://w3id.org/security#multibase" | ||
}, | ||
"proof": { | ||
"@id": "https://w3id.org/security#proof", | ||
"@type": "@id", | ||
"@container": "@graph" | ||
}, | ||
"DataIntegrityProof": { | ||
"@id": "https://w3id.org/security#DataIntegrityProof", | ||
"@context": { | ||
"@protected": true, | ||
"id": "@id", | ||
"type": "@type", | ||
"challenge": "https://w3id.org/security#challenge", | ||
"created": { | ||
"@id": "http://purl.org/dc/terms/created", | ||
"@type": "http://www.w3.org/2001/XMLSchema#dateTime" | ||
}, | ||
"domain": "https://w3id.org/security#domain", | ||
"expires": { | ||
"@id": "https://w3id.org/security#expiration", | ||
"@type": "http://www.w3.org/2001/XMLSchema#dateTime" | ||
}, | ||
"nonce": "https://w3id.org/security#nonce", | ||
"proofPurpose": { | ||
"@id": "https://w3id.org/security#proofPurpose", | ||
"@type": "@vocab", | ||
"@context": { | ||
"@protected": true, | ||
"id": "@id", | ||
"type": "@type", | ||
"assertionMethod": { | ||
"@id": "https://w3id.org/security#assertionMethod", | ||
"@type": "@id", | ||
"@container": "@set" | ||
}, | ||
"authentication": { | ||
"@id": "https://w3id.org/security#authenticationMethod", | ||
"@type": "@id", | ||
"@container": "@set" | ||
}, | ||
"capabilityInvocation": { | ||
"@id": "https://w3id.org/security#capabilityInvocationMethod", | ||
"@type": "@id", | ||
"@container": "@set" | ||
}, | ||
"capabilityDelegation": { | ||
"@id": "https://w3id.org/security#capabilityDelegationMethod", | ||
"@type": "@id", | ||
"@container": "@set" | ||
}, | ||
"keyAgreement": { | ||
"@id": "https://w3id.org/security#keyAgreementMethod", | ||
"@type": "@id", | ||
"@container": "@set" | ||
} | ||
} | ||
}, | ||
"cryptosuite": "https://w3id.org/security#cryptosuite", | ||
"proofValue": { | ||
"@id": "https://w3id.org/security#proofValue", | ||
"@type": "https://w3id.org/security#multibase" | ||
}, | ||
"verificationMethod": { | ||
"@id": "https://w3id.org/security#verificationMethod", | ||
"@type": "@id" | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.