├── .gitignore
├── artifacts
├── README.md
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── src
│ ├── main
│ │ ├── resources
│ │ │ ├── issuance
│ │ │ │ ├── example
│ │ │ │ │ ├── credential-status.json
│ │ │ │ │ ├── credential-message-rejected.json
│ │ │ │ │ ├── credential-request-message.json
│ │ │ │ │ ├── credential-message.json
│ │ │ │ │ ├── credential-object.json
│ │ │ │ │ ├── credential-offer-message.json
│ │ │ │ │ └── issuer-metadata.json
│ │ │ │ ├── credential-offer-message-schema.json
│ │ │ │ ├── credential-request-message-schema.json
│ │ │ │ ├── credential-object-schema.json
│ │ │ │ ├── credential-status-schema.json
│ │ │ │ ├── issuer-metadata-schema.json
│ │ │ │ └── credential-message-schema.json
│ │ │ ├── presentation
│ │ │ │ ├── example
│ │ │ │ │ ├── presentation-query-message.json
│ │ │ │ │ ├── presentation-response-message.json
│ │ │ │ │ ├── presentation-response-message-w-presentation-submission.json
│ │ │ │ │ └── presentation-query-message-w-presentation-definition.json
│ │ │ │ ├── presentation-response-message-schema.json
│ │ │ │ └── presentation-query-message-schema.json
│ │ │ ├── common
│ │ │ │ └── context-schema.json
│ │ │ └── context
│ │ │ │ ├── dcp.jsonld
│ │ │ │ └── odrl.jsonld
│ │ └── java
│ │ │ └── org
│ │ │ └── eclipse
│ │ │ └── dcp
│ │ │ └── schema
│ │ │ └── SchemaConstants.java
│ └── test
│ │ ├── resources
│ │ ├── claim-format-registry
│ │ │ └── schemas
│ │ │ │ ├── presentation-submission-claim-format-designations.json
│ │ │ │ └── presentation-definition-claim-format-designations.json
│ │ └── presentation-exchange
│ │ │ └── schemas
│ │ │ ├── presentation-submission.json
│ │ │ └── presentation-definition.json
│ │ └── java
│ │ └── org
│ │ └── eclipse
│ │ └── dcp
│ │ ├── context
│ │ ├── presentation
│ │ │ └── PresentationContextTest.java
│ │ ├── issuance
│ │ │ └── IssuanceContextTest.java
│ │ └── fixtures
│ │ │ └── AbstractJsonLdTest.java
│ │ └── schema
│ │ ├── fixtures
│ │ └── AbstractSchemaTest.java
│ │ ├── issuance
│ │ ├── CredentialStatusSchemaTest.java
│ │ ├── CredentialOfferMessageSchemaTest.java
│ │ ├── IssuerMetadataSchemaTest.java
│ │ ├── CredentialObjectSchemaTest.java
│ │ ├── CredentialRequestMessageSchemaTest.java
│ │ └── CredentialMessageSchemaTest.java
│ │ └── presentation
│ │ ├── PresentationResponseMessageSchemaTest.java
│ │ └── PresentationQueryMessageSchemaTest.java
├── settings.gradle.kts
├── .gitignore
├── config
│ └── checkstyle
│ │ └── suppressions.xml
├── build.gradle.kts
├── gradlew.bat
└── gradlew
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── 1-bug.yml
│ └── 2-feature-request.yml
├── actions
│ └── setup-java
│ │ └── action.yaml
├── PULL_REQUEST_TEMPLATE.md
├── scripts
│ ├── index.html
│ └── checkout-tags.sh
└── workflows
│ ├── artifacts.yaml
│ └── autopublish.yaml
├── CODE_OF_CONDUCT.md
├── docs
├── roadmap
│ └── DCP_Roadmap_Plan.pdf
└── decision-records
│ ├── 2023-09-22-release-process
│ └── README.md
│ └── 2024-12-12-profiles
│ └── README.md
├── SECURITY.md
├── specifications
├── auth.flow.puml
├── issuance.flow.puml
├── dsp.profile.md
├── terminology.md
├── diagram.styles.puml
├── identity-trust-sts-api.yaml
├── dataspace.ecosystem.md
├── dcp.profiles.md
├── issuer-holder-verifier-model.svg
├── base.protocol.md
├── participant-agent-model.svg
├── trust.model.md
├── auth.flow.svg
└── issuance.flow.svg
├── README.md
├── NOTICE.md
├── CONTRIBUTING.md
├── WEBSITE.md
├── pr_etiquette.md
├── index.html
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | resources/
--------------------------------------------------------------------------------
/artifacts/README.md:
--------------------------------------------------------------------------------
1 | # DCP Artifacts
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | See the [Eclipse Code Of Conduct](https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php).
--------------------------------------------------------------------------------
/docs/roadmap/DCP_Roadmap_Plan.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eclipse-dataspace-dcp/decentralized-claims-protocol/HEAD/docs/roadmap/DCP_Roadmap_Plan.pdf
--------------------------------------------------------------------------------
/artifacts/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/eclipse-dataspace-dcp/decentralized-claims-protocol/HEAD/artifacts/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Reporting a Vulnerability
4 |
5 | Please report a found vulnerability here:
6 | [https://www.eclipse.org/security/](https://www.eclipse.org/security/)
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-status.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "CredentialStatus",
6 | "issuerPid": "issuerPid",
7 | "holderPid": "holderPid",
8 | "status": "RECEIVED"
9 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/example/presentation-query-message.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "PresentationQueryMessage",
6 | "scope": [
7 | "presentation1",
8 | "presentation2"
9 | ]
10 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/example/presentation-response-message.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "PresentationResponseMessage",
6 | "presentation": [
7 | "presentation1",
8 | "presentation2"
9 | ]
10 | }
--------------------------------------------------------------------------------
/.github/actions/setup-java/action.yaml:
--------------------------------------------------------------------------------
1 | name: "Setup JDK 17"
2 | description: "Setup JDK 17"
3 | runs:
4 | using: "composite"
5 | steps:
6 | - name: Setup JDK 17
7 | uses: actions/setup-java@v4.1.0
8 | with:
9 | java-version: '17'
10 | distribution: 'temurin'
11 | cache: 'gradle'
12 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-message-rejected.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "CredentialMessage",
6 | "issuerPid": "issuerPid",
7 | "holderPid": "holderPid",
8 | "status": "REJECTED",
9 | "rejectionReason": "final approval not granted"
10 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-request-message.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "CredentialRequestMessage",
6 | "holderPid": "holderPid",
7 | "credentials": [
8 | {
9 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1"
10 | },
11 | {
12 | "id": "c0f81e68-6d35-4f9d-bc04-51e511b2e46c"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## WHAT
2 |
3 | _Briefly describe what your PR changes, which features it adds/modifies._
4 |
5 | Closes # <-- _insert Issue number if one exists_
6 |
7 | ## How was the issue fixed?
8 |
9 | _Briefly state why the change was necessary._
10 |
11 | ## More context
12 |
13 | _List other areas that have changed but are not necessarily linked to the main feature. This could be naming changes,
14 | bugs that were encountered and were fixed inline, etc._
--------------------------------------------------------------------------------
/artifacts/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | rootProject.name = "artifacts"
--------------------------------------------------------------------------------
/.github/scripts/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 | This redirects to the latest Release here
12 |
13 |
14 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-message.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "CredentialMessage",
6 | "credentials": [
7 | {
8 | "credentialType": "MembershipCredential",
9 | "payload": "",
10 | "format": "jwt"
11 | },
12 | {
13 | "credentialType": "OrganizationCredential",
14 | "payload": "",
15 | "format": "json-ld"
16 | }
17 | ],
18 | "issuerPid": "issuerPid",
19 | "holderPid": "holderPid",
20 | "status": "ISSUED"
21 | }
--------------------------------------------------------------------------------
/artifacts/src/test/resources/claim-format-registry/schemas/presentation-submission-claim-format-designations.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "title": "Presentation Submission Claim Format Designations",
4 | "type": "object",
5 | "definitions": {
6 | "format": {
7 | "type": "string",
8 | "enum": [
9 | "jwt",
10 | "jwt_vc",
11 | "jwt_vp",
12 | "ldp",
13 | "ldp_vc",
14 | "ldp_vp",
15 | "mso_mdoc",
16 | "ac_vc",
17 | "ac_vp",
18 | "sd_jwt"
19 | ]
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/common/context-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "ContextSchema",
4 | "type": "array",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/ContextSchema"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v08/common/context-schema.json",
11 | "definitions": {
12 | "ContextSchema": {
13 | "type": "array",
14 | "items": {
15 | "type": "string",
16 | "items": {
17 | "type": "string"
18 | }
19 | },
20 | "contains": {
21 | "const": "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
22 | }
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/specifications/auth.flow.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | !pragma layout smetana
3 |
4 | !include diagram.styles.puml
5 |
6 | autonumber
7 |
8 | box "Client Entity"
9 | participant "Client" as C
10 | participant "Secure Token Service" as STS
11 | participant "DID Service" as DS
12 | participant "Credential Service" as CS
13 | end box
14 |
15 | box "Verifier Entity"
16 | participant "Verifier" as V
17 | end box
18 |
19 | C -> STS: request
20 | STS -> C: response incl. access token
21 |
22 | C -> V: request w/ self-issued id token incl. access token
23 | DS <- V: resolve DID
24 | DS -> V: DID document response
25 | CS <- V: request w/ self-issued id token incl. access token
26 | CS ->V: VP response
27 | C <- V: response
28 | @enduml
--------------------------------------------------------------------------------
/artifacts/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2024 Metaform Systems, Inc.
3 | #
4 | # This program and the accompanying materials are made available under the
5 | # terms of the Apache License, Version 2.0 which is available at
6 | # https://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # SPDX-License-Identifier: Apache-2.0
9 | #
10 | # Contributors:
11 | # Metaform Systems, Inc. - initial API and implementation
12 | #
13 | #
14 |
15 | distributionBase=GRADLE_USER_HOME
16 | distributionPath=wrapper/dists
17 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
18 | networkTimeout=10000
19 | validateDistributionUrl=true
20 | zipStoreBase=GRADLE_USER_HOME
21 | zipStorePath=wrapper/dists
22 |
--------------------------------------------------------------------------------
/artifacts/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build/
3 | !gradle/wrapper/gradle-wrapper.jar
4 | !**/src/main/**/build/
5 | !**/src/test/**/build/
6 |
7 | ### IntelliJ IDEA ###
8 | .idea/modules.xml
9 | .idea/jarRepositories.xml
10 | .idea/compiler.xml
11 | .idea/libraries/
12 | *.iws
13 | *.iml
14 | *.ipr
15 | .idea
16 | out/
17 | !**/src/main/**/out/
18 | !**/src/test/**/out/
19 |
20 | ### Eclipse ###
21 | .apt_generated
22 | .classpath
23 | .factorypath
24 | .project
25 | .settings
26 | .springBeans
27 | .sts4-cache
28 | bin/
29 | !**/src/main/**/bin/
30 | !**/src/test/**/bin/
31 |
32 | ### NetBeans ###
33 | /nbproject/private/
34 | /nbbuild/
35 | /dist/
36 | /nbdist/
37 | /.nb-gradle/
38 |
39 | ### VS Code ###
40 | .vscode/
41 |
42 | ### Mac OS ###
43 | .DS_Store
44 |
45 |
46 |
--------------------------------------------------------------------------------
/artifacts/config/checkstyle/suppressions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/example/presentation-response-message-w-presentation-submission.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "PresentationResponseMessage",
6 | "presentation": [
7 | "jwtPresentation"
8 | ],
9 | "presentationSubmission": {
10 | "id": "Presentation example 2",
11 | "definition_id": "Example with multiple VPs",
12 | "descriptor_map": [
13 | {
14 | "id": "id_credential",
15 | "format": "jwt_vp",
16 | "path": "$.presentation[0]",
17 | "path_nested": {
18 | "id": "id_nested_credential",
19 | "format": "jwt_vc",
20 | "path": "$.vp.verifiableCredential[0]"
21 | }
22 | }
23 | ]
24 | }
25 | }
--------------------------------------------------------------------------------
/specifications/issuance.flow.puml:
--------------------------------------------------------------------------------
1 | @startuml
2 | !pragma layout smetana
3 |
4 | !include diagram.styles.puml
5 |
6 | autonumber
7 |
8 | box "Client Entity"
9 | participant "Client" as C
10 | participant "Secure Token Service" as STS
11 | participant "DID Service" as DS
12 | participant "Credential Service" as CS
13 | end box
14 |
15 | box "Issuer Entity"
16 | participant "Issuer Service" as IS
17 | end box
18 |
19 | C -> STS: request
20 | STS -> C: response incl. access token
21 | C -> IS: request credential(s) w/ self-issued ID token incl. access token
22 | DS <- IS: resolve DID
23 | DS -> IS: DID document response
24 | C <- IS: ack
25 | CS <- IS: (async) write credential(s)\n w/ self-issued ID token access token
26 | CS -> CS: Validate token and\n store credentials
27 |
28 | @enduml
29 |
--------------------------------------------------------------------------------
/.github/scripts/checkout-tags.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir -p HEAD
4 | git fetch --all --tags
5 | tags_string=$(git tag)
6 | echo got tag string
7 | echo $tags_string
8 | tags_array=($tags_string)
9 | mv * HEAD
10 | for tag in "${tags_array[@]}"
11 | do
12 | echo starting with tag $tag
13 | mkdir $tag
14 | cd $tag
15 | git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git --depth 1 --branch ${tag} --quiet
16 | pwd
17 | mv ./decentralized-claims-protocol/* .
18 | cd ..
19 | done
20 | pwd
21 | for dir in */; do
22 | if [ -f "$dir/index.html" ]; then
23 | echo "index exists."
24 | mkdir -p $dir/resources
25 | cp -r $dir/artifacts/src/main/resources/* $dir/resources
26 | rm -rf $dir/artifacts
27 | else
28 | echo "index does not exist. No copy operations"
29 | fi
30 | done
--------------------------------------------------------------------------------
/artifacts/src/main/java/org/eclipse/dcp/schema/SchemaConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema;
16 |
17 | /**
18 | * Defines constants for schema validation.
19 | */
20 | public interface SchemaConstants {
21 |
22 | String DCP_CONTEXT = "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld";
23 | String DCP_PREFIX = "https://w3id.org/dspace-dcp/v1.0/";
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/artifacts.yaml:
--------------------------------------------------------------------------------
1 | name: Verify Artifacts
2 |
3 | on:
4 | workflow_call:
5 |
6 | workflow_dispatch:
7 |
8 | pull_request:
9 | paths:
10 | - "artifacts/**"
11 |
12 | jobs:
13 | verify-formatting:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 |
18 | - uses: ./.github/actions/setup-java
19 | - name: Run Checkstyle
20 | working-directory: ./artifacts
21 | run: |
22 | ./gradlew checkstyleMain checkstyleTest
23 |
24 | verify-artifacts:
25 | runs-on: ubuntu-latest
26 | steps:
27 | - name: Checkout
28 | uses: actions/checkout@v4
29 | - uses: ./.github/actions/setup-java
30 | - name: Checks artifacts
31 | working-directory: ./artifacts
32 | run: |
33 | ./gradlew test
34 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/example/presentation-query-message-w-presentation-definition.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "PresentationQueryMessage",
6 | "presentationDefinition": {
7 | "id": "presentation1",
8 | "input_descriptors": [
9 | {
10 | "id": "organization credential",
11 | "format": {
12 | "ldp_vc": {
13 | "proof_type": [
14 | "Ed25519Signature2018"
15 | ]
16 | }
17 | },
18 | "constraints": {
19 | "fields": [
20 | {
21 | "path": [
22 | "$.type"
23 | ],
24 | "filter": {
25 | "type": "string",
26 | "pattern": "OrganizationCredential"
27 | }
28 | }
29 | ]
30 | }
31 | }
32 | ]
33 | }
34 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-object.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
6 | "type": "CredentialObject",
7 | "credentialType": "CompanyCredential",
8 | "credentialSchema": "https://example.com/credentials/credentialSchema",
9 | "offerReason": "reissue",
10 | "bindingMethods": [
11 | "did:web"
12 | ],
13 | "profile": "vc20-bssl/jwt",
14 | "issuancePolicy": {
15 | "id": "Scalable trust example",
16 | "input_descriptors": [
17 | {
18 | "id": "pd-id",
19 | "constraints": {
20 | "fields": [
21 | {
22 | "path": [
23 | "$.vc.type"
24 | ],
25 | "filter": {
26 | "type": "string",
27 | "pattern": "^AttestationCredential$"
28 | }
29 | }
30 | ]
31 | }
32 | }
33 | ]
34 | }
35 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/credential-offer-message.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "CredentialOfferMessage",
6 | "issuer": "issuer",
7 | "credentials": [
8 | {
9 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
10 | "type": "CredentialObject",
11 | "credentialType": "CompanyCredential",
12 | "offerReason": "reissue",
13 | "bindingMethods": [
14 | "did:web"
15 | ],
16 | "profile": "vc10-sl2021/jwt",
17 | "issuancePolicy": {
18 | "id": "Scalable trust example",
19 | "input_descriptors": [
20 | {
21 | "id": "pd-id",
22 | "constraints": {
23 | "fields": [
24 | {
25 | "path": [
26 | "$.vc.type"
27 | ],
28 | "filter": {
29 | "type": "string",
30 | "pattern": "^AttestationCredential$"
31 | }
32 | }
33 | ]
34 | }
35 | }
36 | ]
37 | }
38 | }
39 | ]
40 | }
--------------------------------------------------------------------------------
/docs/decision-records/2023-09-22-release-process/README.md:
--------------------------------------------------------------------------------
1 | # Defining a simple release process
2 |
3 | ## Decision
4 |
5 | The release process for the specifications should be simple and easy to understand. We will not follow GitFlow, but
6 | employ a simple tag-based approach.
7 |
8 | ## Rationale
9 |
10 | With code artefacts it is oftentimes required to be able to back-port bugfixes or even features, or maintain older
11 | versions. Here, the deliverable is merely a compressed archive with static non-code content, so the release process can
12 | be kept fairly simple and linear.
13 |
14 | ## Approach
15 |
16 | Every release will be tagged on the `main` branch using semantic versioning, starting at `0.1.0`. Then,
17 | using that tag, a GitHub Release is to be created, for example using the `ncipollo/release-action` GitHub action.
18 | Finally, a compressed archive containing the current specification documents will be uploaded as artefact to the
19 | GitHub release.
20 |
21 | ## Further notes
22 |
23 | Even though it is common to create a separate branch containing just the release commit (often named `releases`), there
24 | is no apparent advantage over the tag-only approach.
--------------------------------------------------------------------------------
/.github/workflows/autopublish.yaml:
--------------------------------------------------------------------------------
1 | name: Auto-Publish
2 | on:
3 | push:
4 | branches:
5 | - main
6 | workflow_dispatch:
7 |
8 | jobs:
9 | tests-artifacts:
10 | uses: ./.github/workflows/artifacts.yaml
11 | build:
12 | name: Build and Validate
13 | runs-on: ubuntu-22.04
14 | permissions:
15 | contents: write
16 | steps:
17 | - uses: actions/checkout@v4
18 | - uses: actions/setup-node@v4
19 | with:
20 | node-version: 22.x
21 | - name: Create Release folders
22 | run: |
23 | chmod +x .github/scripts/checkout-tags.sh
24 | ./.github/scripts/checkout-tags.sh
25 | - name: Redirect top to head
26 | run: cp .github/scripts/index.html .
27 | - uses: actions/upload-pages-artifact@v3
28 | with:
29 | path: .
30 | deploy:
31 | needs: build
32 | permissions:
33 | pages: write
34 | id-token: write
35 | environment:
36 | name: github-pages
37 | url: ${{ steps.deployment.outputs.page_url }}
38 | runs-on: ubuntu-22.04
39 | steps:
40 | - name: Deploy to GitHub Pages
41 | id: deployment
42 | uses: actions/deploy-pages@v4
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Decentralized Claims Protocol DCP
2 |
3 | This repository contains normative documents defining protocols and flows of the Eclipse Decentralized Claims Protocol
4 | Specification (DCP). The specification defines an interoperable overlay to
5 | the [Dataspace Protocol Specification (DSP)](https://github.com/eclipse-dataspace-protocol-base/DataspaceProtocol) for
6 | conveying organizational identities and establishing trust in a way that preserves privacy and limits the possibility of
7 | network disruption.
8 |
9 | The scope of the Eclipse DCP specification includes:
10 |
11 | - Specifying a format for self-issued identity tokens
12 | - Defining a protocol for storing and presenting Verifiable Credentials and other identity-related resources
13 | - Defining a protocol for parties to request credentials from a credential issuer
14 |
15 | Eclipse DCP supports multiple trust anchors and allows participants to manage and verify presentations without needing
16 | third-party systems outside their control.
17 |
18 | ## Technology Compatibility Kit
19 |
20 | Eclipse DCP includes a [Technology Compatibility Kit (TCK)](https://github.com/eclipse-dataspacetck/dcp-tck) that can be
21 | used to test implementation compliance to the specification.
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/credential-offer-message-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "CredentialOfferMessageSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/CredentialOfferMessage"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-offer-message-schema.json",
11 | "definitions": {
12 | "CredentialOfferMessage": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "issuer": {
19 | "type": "string"
20 | },
21 | "credentials": {
22 | "type": "array",
23 | "items": {
24 | "$ref": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-object-schema.json#/definitions/CredentialObject"
25 | }
26 | },
27 | "type": {
28 | "type": "string",
29 | "const": "CredentialOfferMessage"
30 | }
31 | },
32 | "required": [
33 | "@context",
34 | "issuer",
35 | "credentials",
36 | "type"
37 | ]
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/example/issuer-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "@context": [
3 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
4 | ],
5 | "type": "IssuerMetadata",
6 | "issuer": "did:web:issuer-url",
7 | "credentialsSupported": [
8 | {
9 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
10 | "type": "CredentialObject",
11 | "credentialType": "CompanyCredential",
12 | "offerReason": "reissue",
13 | "credentialSchema": "https://example.com/company-credential-schema.json",
14 | "bindingMethods": [
15 | "did:web"
16 | ],
17 | "profile": "vc10-sl2021/jwt",
18 | "issuancePolicy": {
19 | "id": "Scalable trust example",
20 | "input_descriptors": [
21 | {
22 | "id": "pd-id",
23 | "constraints": {
24 | "fields": [
25 | {
26 | "path": [
27 | "$.vc.type"
28 | ],
29 | "filter": {
30 | "type": "string",
31 | "pattern": "^AttestationCredential$"
32 | }
33 | }
34 | ]
35 | }
36 | }
37 | ]
38 | }
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/artifacts/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | plugins {
16 | `java-library`
17 | checkstyle
18 | }
19 |
20 | repositories {
21 | mavenCentral()
22 | }
23 |
24 | dependencies {
25 | implementation("com.networknt:json-schema-validator:1.5.2") {
26 | exclude("com.fasterxml.jackson.dataformat", "jackson-dataformat-yaml")
27 | }
28 |
29 | testImplementation("org.assertj:assertj-core:3.26.3")
30 | testImplementation("com.apicatalog:titanium-json-ld:1.4.1")
31 | testImplementation("org.glassfish:jakarta.json:2.0.1")
32 | testImplementation("com.fasterxml.jackson.core:jackson-databind:2.18.0")
33 | testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jakarta-jsonp:2.18.0")
34 | }
35 |
36 | testing {
37 | suites {
38 | val test by getting(JvmTestSuite::class) {
39 | useJUnitJupiter("5.8.1")
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/credential-request-message-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "CredentialRequestMessageSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/CredentialRequestMessage"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-request-message-schema.json",
11 | "definitions": {
12 | "CredentialRequestMessage": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "type": {
19 | "type": "string"
20 | },
21 | "holderPid": {
22 | "type": "string"
23 | },
24 | "credentials": {
25 | "type": "array",
26 | "items": {
27 | "type": "object",
28 | "properties": {
29 | "id": {
30 | "type": "string"
31 | }
32 | },
33 | "required": [
34 | "id"
35 | ]
36 | }
37 | }
38 | },
39 | "required": [
40 | "@context",
41 | "holderPid",
42 | "credentials",
43 | "type"
44 | ]
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/NOTICE.md:
--------------------------------------------------------------------------------
1 | # Notices for Eclipse Dataspace DCP
2 |
3 | This content is produced and maintained by the Eclipse Decentralized Claims Protocol project.
4 |
5 | ## Trademarks
6 |
7 | Eclipse Decentralized Claims Protocol is a trademark of the Eclipse Foundation.
8 |
9 | ## Copyright
10 |
11 | All content is the property of the respective authors or their employers. For
12 | more information regarding authorship of content, please consult the listed
13 | source code repository logs.
14 |
15 | ## Declared Project Licenses
16 |
17 | This specification project repository uses the following license:
18 |
19 | - XXX
20 |
21 | ## Source Code
22 |
23 | The project maintains the following source code repositories
24 | in the GitHub organization https://github.com/eclipse-dataspace-dcp:
25 |
26 | * https://github.com/eclipse-dataspace-dcp/decentralized-claims-protocol
27 |
28 | ## Third-party Content
29 |
30 | N/A
31 |
32 | ## Cryptography
33 |
34 | Content may contain encryption software. The country in which you are currently
35 | may have restrictions on the import, possession, and use, and/or re-export to
36 | another country, of encryption software. BEFORE using any encryption software,
37 | please check the country's laws, regulations and policies concerning the import,
38 | possession, or use, and re-export of encryption software, to see if this is
39 | permitted.
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/presentation-response-message-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "PresentationResponseMessageSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/PresentationResponseMessage"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/presentation/presentation-response-message-schema.json",
11 | "definitions": {
12 | "PresentationResponseMessage": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "presentation": {
19 | "type": "array",
20 | "items": {
21 | "type": [
22 | "object",
23 | "string"
24 | ]
25 | }
26 | },
27 | "presentationSubmission": {
28 | "$ref": "https://identity.foundation/presentation-exchange/schemas/presentation-submission.json#/properties/presentation_submission"
29 | },
30 | "type": {
31 | "type": "string",
32 | "const": "PresentationResponseMessage"
33 | }
34 | },
35 | "required": [
36 | "@context",
37 | "type",
38 | "presentation"
39 | ]
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/artifacts/src/test/resources/claim-format-registry/schemas/presentation-definition-claim-format-designations.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "title": "Presentation Definition Claim Format Designations",
4 | "type": "object",
5 | "additionalProperties": false,
6 | "patternProperties": {
7 | "^jwt$|^jwt_vc$|^jwt_vp$": {
8 | "type": "object",
9 | "additionalProperties": false,
10 | "properties": {
11 | "alg": {
12 | "type": "array",
13 | "minItems": 1,
14 | "items": {
15 | "type": "string"
16 | }
17 | }
18 | }
19 | },
20 | "^ldp_vc$|^ldp_vp$|^ldp$": {
21 | "type": "object",
22 | "additionalProperties": false,
23 | "properties": {
24 | "proof_type": {
25 | "type": "array",
26 | "minItems": 1,
27 | "items": {
28 | "type": "string"
29 | }
30 | }
31 | }
32 | },
33 | "^ac_vc$|^ac_vp$": {
34 | "type": "object",
35 | "additionalProperties": false,
36 | "properties": {
37 | "proof_type": {
38 | "type": "array",
39 | "minItems": 1,
40 | "items": {
41 | "type": "string"
42 | }
43 | }
44 | }
45 | },
46 | "mso_mdoc": {
47 | "type": "object"
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1-bug.yml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: Create a report to improve maturity of the spec!
3 | labels: ["bug", "triage"]
4 | body:
5 | - type: textarea
6 | id: what
7 | attributes:
8 | label: What's wrong?
9 | placeholder: Reasons could be contradictions (internally or to external standards), ambiguities, wrong schema files, writing
10 | validations:
11 | required: true
12 | - type: textarea
13 | id: why
14 | attributes:
15 | label: Why is this a bug?
16 | description: Also tell us, what did you expect to happen?
17 | validations:
18 | required: true
19 | - type: textarea
20 | id: how
21 | attributes:
22 | label: How could it be fixed?
23 | description: Feel free to suggest and weigh several resolution strategies. Omit if obvious.
24 | - type: textarea
25 | id: context
26 | attributes:
27 | label: More context
28 | description: If applicable, add additional info to help explain your problem.
29 | - type: markdown
30 | attributes:
31 | value: |
32 | _Please be sure to take a look at
33 | our [contribution guidelines](https://github.com/eclipse-dataspace-dcp/decentralized-claims-protocol/blob/main/CONTRIBUTING.md) and
34 | our [PR etiquette](https://github.com/eclipse-dataspace-dcp/decentralized-claims-protocol/blob/main/pr_etiquette.md)._
--------------------------------------------------------------------------------
/artifacts/src/main/resources/presentation/presentation-query-message-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "PresentationQueryMessageSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/PresentationQueryMessage"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/presentation/presentation-query-message-schema.json",
11 | "definitions": {
12 | "PresentationQueryMessage": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "type": {
19 | "type": "string",
20 | "const": "PresentationQueryMessage"
21 | },
22 | "scope": {
23 | "type": "array",
24 | "minItems": 1,
25 | "items": {
26 | "type": "string"
27 | }
28 | },
29 | "presentationDefinition": {
30 | "type": "object",
31 | "$ref": "https://identity.foundation/presentation-exchange/schemas/presentation-definition.json"
32 | }
33 | },
34 | "anyOf": [
35 | { "required": ["scope"] },
36 | { "required": ["presentationDefinition"] }
37 | ],
38 | "required": [
39 | "@context",
40 | "type"
41 | ]
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/docs/decision-records/2024-12-12-profiles/README.md:
--------------------------------------------------------------------------------
1 | # Interop Profiles for DCP
2 |
3 | ## Decision
4 |
5 | DCP will define two interop profiles that constrain the VC data model, the revocation system and the proof stack.
6 |
7 | ## Rationale
8 |
9 | In order to provide to implementors a way to establish interoperability without having to define a whole profile, DCP will specify two standard profiles.
10 | These profiles are the "sane defaults" for which DCP will also provide Technology Compatibility Kits.
11 |
12 | ## Approach
13 |
14 | Profiles are defined using an _alias_ that should be indicative of what they contain:
15 | - `vc20+bssl/jwt`: uses VC Data Model 2.0, BitStringStatusList as revocation system and enveloped proofs as JWT
16 | - `vc11+sl2021/jwt`: uses VC Data Model 1.1, StatusList2021 as revocation system and external proofs in the form of JWT
17 |
18 |
19 | In the specification document, the `CredentialObject` will be modified such that the `credentials[].format` and `credentials[].cryptography` properties get collapsed into the `credentials[].profile` property, which should contain the profile alias, e.g. `vc20+bssl/jwt`.
20 |
21 | ## Further notes
22 |
23 | As an added bonus, the specification document should contain a non-normative text passage that outlines, which decisions authors of subsequent profiles need to make, i.e. the minimum set of things a profile descriptions should specify.
24 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/credential-object-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "CredentialObjectSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/CredentialObject"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-object-schema.json",
11 | "definitions": {
12 | "CredentialObject": {
13 | "type": "object",
14 | "properties": {
15 | "id": {
16 | "type": "string",
17 | "format": "uri"
18 | },
19 | "credentialType": {
20 | "type": "string"
21 | },
22 | "credentialSchema": {
23 | "type": "string"
24 | },
25 | "offerReason": {
26 | "type": "string"
27 | },
28 | "bindingMethods": {
29 | "type": "array",
30 | "items": {
31 | "type": "string"
32 | }
33 | },
34 | "profile": {
35 | "type": "string"
36 | },
37 | "issuancePolicy": {
38 | "type": "object",
39 | "$ref": "https://identity.foundation/presentation-exchange/schemas/presentation-definition.json"
40 | },
41 | "type": {
42 | "type": "string",
43 | "const": "CredentialObject"
44 | }
45 | },
46 | "required": [
47 | "id",
48 | "type"
49 | ]
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-feature-request.yml:
--------------------------------------------------------------------------------
1 | name: Feature Request Report
2 | description: Tell us about your idea and request a new feature
3 | labels: ["enhancement", "triage"]
4 | body:
5 | - type: textarea
6 | id: what
7 | attributes:
8 | label: What's missing?
9 | placeholder: Describe what the spec should govern but currently doesn't
10 | validations:
11 | required: true
12 | - type: textarea
13 | id: why
14 | attributes:
15 | label: Why should it be in the spec?
16 | description: Explain why this is an issue for DCP specifically. Reasons might be to eliminate ambiguity or take new functionality into scope.
17 | validations:
18 | required: true
19 | - type: textarea
20 | id: where
21 | attributes:
22 | label: Where should this be added?
23 | description: What location in the existing structure could be extended to accommodate the proposed feature?
24 | - type: textarea
25 | id: context
26 | attributes:
27 | label: More context
28 | description: If applicable, add additional info to help explain your problem.
29 | - type: markdown
30 | attributes:
31 | value: |
32 | _Please be sure to take a look at
33 | our [contribution guidelines](https://github.com/eclipse-dataspace-dcp/decentralized-claims-protocol/blob/main/CONTRIBUTING.md) and
34 | our [PR etiquette](https://github.com/eclipse-dataspace-dcp/decentralized-claims-protocol/blob/main/PR_ETIQUETTE.md)._
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/credential-status-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "CredentialStatusSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/CredentialStatus"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-status-schema.json",
11 | "definitions": {
12 | "CredentialStatusClass": {
13 | "type": "object",
14 | "properties": {
15 | "issuerPid": {
16 | "type": "string"
17 | },
18 | "holderPid": {
19 | "type": "string"
20 | },
21 | "status": {
22 | "type": "string",
23 | "enum": [
24 | "RECEIVED",
25 | "REJECTED",
26 | "ISSUED"
27 | ]
28 | },
29 | "type": {
30 | "type": "string",
31 | "const": "CredentialStatus"
32 | }
33 | },
34 | "required": [
35 | "issuerPid",
36 | "holderPid",
37 | "status",
38 | "type"
39 | ]
40 | },
41 | "CredentialStatus": {
42 | "type": "object",
43 | "allOf": [
44 | {
45 | "$ref": "#/definitions/CredentialStatusClass"
46 | },
47 | {
48 | "properties": {
49 | "@context": {
50 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
51 | }
52 | },
53 | "required": [
54 | "@context"
55 | ]
56 | }
57 | ]
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/issuer-metadata-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "IssuerMetadataSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/IssuerMetadata"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/issuance/issuer-metadata-schema.json",
11 | "definitions": {
12 | "IssuerMetadata": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "credentialsSupported": {
19 | "type": "array",
20 | "items": {
21 | "allOf": [
22 | {
23 | "$ref": "https://w3id.org/dspace-dcp/v1.0/issuance/credential-object-schema.json#/definitions/CredentialObject"
24 | },
25 | {
26 | "type": "object",
27 | "required": [
28 | "credentialType",
29 | "credentialSchema",
30 | "offerReason",
31 | "bindingMethods",
32 | "profile"
33 | ]
34 | }
35 | ]
36 | }
37 | },
38 | "issuer": {
39 | "type": "string"
40 | },
41 | "type": {
42 | "type": "string",
43 | "const": "IssuerMetadata"
44 | }
45 | },
46 | "required": [
47 | "@context",
48 | "issuer",
49 | "credentialsSupported",
50 | "type"
51 | ]
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/artifacts/src/test/resources/presentation-exchange/schemas/presentation-submission.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/draft-07/schema#",
3 | "title": "Presentation Submission",
4 | "type": "object",
5 | "properties": {
6 | "presentation_submission": {
7 | "type": "object",
8 | "properties": {
9 | "id": {
10 | "type": "string"
11 | },
12 | "definition_id": {
13 | "type": "string"
14 | },
15 | "descriptor_map": {
16 | "type": "array",
17 | "items": {
18 | "$ref": "#/definitions/descriptor"
19 | }
20 | }
21 | },
22 | "required": [
23 | "id",
24 | "definition_id",
25 | "descriptor_map"
26 | ],
27 | "additionalProperties": false
28 | }
29 | },
30 | "definitions": {
31 | "descriptor": {
32 | "type": "object",
33 | "properties": {
34 | "id": {
35 | "type": "string"
36 | },
37 | "path": {
38 | "type": "string"
39 | },
40 | "path_nested": {
41 | "type": "object",
42 | "$ref": "#/definitions/descriptor"
43 | },
44 | "format": {
45 | "$ref": "https://identity.foundation/claim-format-registry/schemas/presentation-submission-claim-format-designations.json#/definitions/format"
46 | }
47 | },
48 | "required": [
49 | "id",
50 | "path",
51 | "format"
52 | ],
53 | "additionalProperties": false
54 | }
55 | },
56 | "required": [
57 | "presentation_submission"
58 | ],
59 | "additionalProperties": false
60 | }
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/context/presentation/PresentationContextTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.context.presentation;
16 |
17 | import org.eclipse.dcp.context.fixtures.AbstractJsonLdTest;
18 | import org.junit.jupiter.api.Test;
19 |
20 | public class PresentationContextTest extends AbstractJsonLdTest {
21 |
22 | @Test
23 | void verifyPresentationQueryMessage() {
24 | verifyRoundTrip("/presentation/example/presentation-query-message.json", "/presentation/presentation-query-message-schema.json");
25 | }
26 |
27 | @Test
28 | void verifyPresentationQueryMessage_withPresentationDefinition() {
29 | verifyRoundTrip("/presentation/example/presentation-query-message-w-presentation-definition.json", "/presentation/presentation-query-message-schema.json");
30 | }
31 |
32 | @Test
33 | void verifyPresentationResponseMessage() {
34 | verifyRoundTrip("/presentation/example/presentation-response-message.json", "/presentation/presentation-response-message-schema.json");
35 | }
36 |
37 | @Test
38 | void verifyPresentationResponseMessage_withPresentationSubmission() {
39 | verifyRoundTrip("/presentation/example/presentation-response-message-w-presentation-submission.json", "/presentation/presentation-response-message-schema.json");
40 | }
41 | }
--------------------------------------------------------------------------------
/specifications/dsp.profile.md:
--------------------------------------------------------------------------------
1 | # 1. Introduction
2 |
3 | This document defines a profile of
4 | the [Dataspace Protocol Specifications (DSP)](https://github.com/International-Data-Spaces-Association/ids-specification).
5 |
6 | # Catalog Metadata for the __Well-Known__ Endpoint
7 |
8 | Catalogs that support the [Credential Issuance Protocol (CIP)](credential.issuance.protocol.md) MUST return a JSON
9 | object from the `/.well-known/dspace-trust` endpoint with the following properties:
10 |
11 | - `@context`: REQUIRED. Specifies a valid [Json-Ld context](https://www.w3.org/TR/json-ld11/#the-context).
12 | - `credentialsSupported`: REQUIRED. Contains a Json structure corresponding to the schema
13 | specified [below](#the-credentialssupported-object).
14 |
15 | A non-normative example is:
16 |
17 | ```json
18 | {
19 | "@context": [
20 | ...
21 | ],
22 | "credentialsSupported": [
23 | {
24 | "types": [
25 | "VerifiableCredential",
26 | "CompanyCredential"
27 | ],
28 | "bindingMethod": "did:web",
29 | "cryptographicSuite": "JsonWebSignature2020"
30 | }
31 | ]
32 | }
33 |
34 | ```
35 |
36 | ### The `CredentialsSupported` Object
37 |
38 | The credentials supported contains a single Json Object or an Array of each verifiable credential (VC) supported by the
39 | catalog. The `CredentialsSupported` object contains the following properties:
40 |
41 | - `types`: REQUIRED. An array of verifiable credential type strings the credential corresponds to
42 | - `bindingMethod`: REQUIRED. String that identifies how the credential is bound to the identifier of the
43 | credential holder.
44 | - `profiles` REQUIRED. An array of strings containing the aliases of the [profiles](./dcp.profiles.md), e.g. `"vc20-bssl/jwt"`.
45 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/issuance/credential-message-schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2019-09/schema",
3 | "title": "CredentialMessageSchema",
4 | "type": "object",
5 | "allOf": [
6 | {
7 | "$ref": "#/definitions/CredentialMessage"
8 | }
9 | ],
10 | "$id": "https://w3id.org/dspace-dcp/v1.0/presentation/credential-message-schema.json",
11 | "definitions": {
12 | "CredentialMessage": {
13 | "type": "object",
14 | "properties": {
15 | "@context": {
16 | "$ref": "https://w3id.org/dspace-dcp/v1.0/common/context-schema.json"
17 | },
18 | "credentials": {
19 | "type": "array",
20 | "items": {
21 | "$ref": "https://w3id.org/dspace-dcp/v1.0/presentation/credential-message-schema.json#/definitions/CredentialContainer"
22 | }
23 | },
24 | "issuerPid": {
25 | "type": "string"
26 | },
27 | "holderPid": {
28 | "type": "string"
29 | },
30 | "credentialType": {
31 | "type": "string",
32 | "const": "CredentialMessage"
33 | },
34 | "format": {
35 | "type": "string"
36 | },
37 | "status": {
38 | "type": "string",
39 | "enum": ["ISSUED", "REJECTED"]
40 | },
41 | "rejectionReason": {
42 | "type": "string"
43 | }
44 | },
45 | "required": [
46 | "@context",
47 | "type",
48 | "issuerPid",
49 | "status"
50 | ]
51 | },
52 | "CredentialContainer": {
53 | "type": "object",
54 | "properties": {
55 | "payload": {
56 | "type": [
57 | "string"
58 | ]
59 | },
60 | "credentialType": {
61 | "type": "string"
62 | },
63 | "format": {
64 | "type": "string"
65 | }
66 | },
67 | "required": [
68 | "payload",
69 | "credentialType",
70 | "format"
71 | ]
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/specifications/terminology.md:
--------------------------------------------------------------------------------
1 | # Terminology
2 |
3 | The following terms are used to describe concepts in this specification.
4 |
5 | - Claim - An assertion made about a [=Subject=].
6 | - DID - A decentralized identifier as defined by [[[did-core]]].
7 | - Holder - An entity that possesses a set of identity resources as defined by the [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol).
8 | The holder will typically be the subject of a [=Verifiable Credential=].
9 | - Issuer - An entity that asserts [=claims=] about one or more subjects by issuing
10 | a [=Verifiable Credential=] to a [=Holder=].
11 | - Resource - A resource is an entity managed by the Credential Service such as a [=Verifiable Credential=]
12 | or [=Verifiable Presentation=].
13 | - Subject - The target of a set of claims contained in a [=Verifiable Credential=] as defined
14 | by the [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol). In a dataspace, a subject will be a participant.
15 | - Verifiable Credential A tamper-evident credential
16 | whose authorship can be cryptographically verified as defined by the [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol).
17 | - Verifiable Presentation A tamper-evident
18 | presentation of information whose authorship can be cryptographically verified as defined by [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol).
19 | - Verifiable Data Registry - Maintains identifiers such as [=DIDs=] and [=Verifiable Credential=] schemas in
20 | a dataspace.
21 | - Verifier - An entity that receives a [=Verifiable Credential=], optionally presented inside
22 | a [=Verifiable Presentation=] as defined by the [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol).
23 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Decentralized Claims Protocol Specification Project
2 |
3 | Thanks for your interest in this project.
4 |
5 | ## Project description
6 |
7 | The Decentralized Claims Protocol is a specification project under the governance of the [Eclipse Dataspace Working
8 | Group](https://www.eclipse.org/org/workinggroups/dataspace-charter.php) (EDWG).
9 |
10 | * https://projects.eclipse.org/projects/technology.dataspace-dcp
11 |
12 | ## Project licenses
13 |
14 | This repository uses the following license:
15 |
16 | * XXX
17 |
18 | ## Terms of Use
19 |
20 | This repository is subject to the Terms of Use of the Eclipse Foundation
21 |
22 | * https://www.eclipse.org/legal/termsofuse.php
23 |
24 | ## Developer resources
25 |
26 | Information regarding source code management, builds, coding standards, and
27 | more.
28 |
29 | * https://projects.eclipse.org/projects/technology.dataspace-dcp/governance
30 |
31 | The project maintains the source code repositories in the following GitHub organization:
32 |
33 | * https://github.com/eclipse-dataspace-dcp
34 |
35 | ## Eclipse Development Process
36 |
37 | This Eclipse Foundation open specification project is governed by the Eclipse Foundation
38 | Development Process and operates under the terms of the Eclipse IP Policy.
39 |
40 | * https://eclipse.org/projects/dev_process
41 | * https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf
42 |
43 | ## Eclipse Contributor Agreement
44 |
45 | In order to be able to contribute to Eclipse Foundation projects you must
46 | electronically sign the Eclipse Contributor Agreement (ECA).
47 |
48 | * http://www.eclipse.org/legal/ECA.php
49 |
50 | The ECA provides the Eclipse Foundation with a permanent record that you agree
51 | that each of your contributions will comply with the commitments documented in
52 | the Developer Certificate of Origin (DCO). Having an ECA on file associated with
53 | the email address matching the "Author" field of your contribution's Git commits
54 | fulfills the DCO's requirement that you sign-off on your contributions.
55 |
56 | For more information, please see the Eclipse Committer Handbook:
57 | https://www.eclipse.org/projects/handbook/#resources-commit
58 |
59 | ## Contact
60 |
61 | Contact the project developers via the project's "dev" list.
62 |
63 | * https://accounts.eclipse.org/mailing-list/dataspace-dcp-dev
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/fixtures/AbstractSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.fixtures;
16 |
17 | import com.networknt.schema.JsonSchema;
18 | import com.networknt.schema.JsonSchemaFactory;
19 | import com.networknt.schema.SchemaLocation;
20 | import com.networknt.schema.ValidationMessage;
21 |
22 | import static com.networknt.schema.SpecVersion.VersionFlag.V202012;
23 | import static org.eclipse.dcp.schema.SchemaConstants.DCP_PREFIX;
24 |
25 | /**
26 | * Base test class.
27 | */
28 | public abstract class AbstractSchemaTest {
29 | public static final String PRESENTATION_EXCHANGE_PREFIX = "https://identity.foundation/";
30 | protected static final String MIN_CONTAINS = "minContains";
31 | protected static final String REQUIRED = "required";
32 | protected static final String ONE_OF = "oneOf";
33 | protected static final String TYPE = "type";
34 | protected static final String ENUM = "enum";
35 | private static final String CLASSPATH_SCHEMA = "classpath:/";
36 | protected JsonSchema schema;
37 |
38 | protected void setUp(String schemaFile) {
39 | var schemaFactory = JsonSchemaFactory.getInstance(V202012, builder ->
40 | builder.schemaMappers(schemaMappers ->
41 | schemaMappers.mapPrefix(DCP_PREFIX, CLASSPATH_SCHEMA)
42 | .mapPrefix(PRESENTATION_EXCHANGE_PREFIX, CLASSPATH_SCHEMA))
43 | );
44 |
45 | schema = schemaFactory.getSchema(SchemaLocation.of(DCP_PREFIX + schemaFile));
46 | }
47 |
48 |
49 |
50 | protected SchemaError errorExtractor(ValidationMessage validationMessage) {
51 | return new SchemaError(validationMessage.getProperty(), validationMessage.getType());
52 | }
53 |
54 | protected SchemaError error(String property, String type) {
55 | return new SchemaError(property, type);
56 | }
57 |
58 | public record SchemaError(String property, String type) {
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/specifications/diagram.styles.puml:
--------------------------------------------------------------------------------
1 |
2 |
3 | !$blue = "#066DFA"
4 | !$gray = "#98A3AB"
5 | !$lightGray = "#F4F5F9"
6 | !$darkGray = "#747C94"
7 | !$green = "#24DCC1"
8 | !$blueFill = "#E4EBFA"
9 | !$greenFill = "#CFFBDE"
10 | !$borderRed = "#F40000"
11 | !$lightRed = "#FDCCCC"
12 |
13 | skinparam sequence {
14 | ArrowColor Black
15 | LifeLineBorderColor 000000
16 | LifeLineBackgroundColor #A9DCDF
17 | }
18 |
19 | skinparam roundCorner 10
20 |
21 | skinparam ArrowColor #000000
22 | skinparam ArrowHeadColor #000000
23 | skinparam LifeLineBackgroundColor $darkGray
24 |
25 |
26 | skinparam CloudBackgroundColor $lightGray
27 | skinparam CloudBorderColor $gray
28 | skinparam CloudFontColor Black
29 |
30 | skinparam ArtifactBackgroundColor $lightGray
31 | skinparam ArtifactBorderColor $gray
32 |
33 | skinparam ComponentBackgroundColor $blueFill
34 | skinparam ComponentBorderColor $blue
35 | skinparam ComponentFontColor Black
36 |
37 | skinparam DatabaseBackgroundColor $greenFill
38 | skinparam DatabaseBorderColor $green
39 | skinparam DatabaseFontColor Black
40 |
41 | skinparam ParticipantBorderColor $blue
42 | skinparam ParticipantBackgroundColor $blueFill
43 | skinparam SequenceGroupBorderColor #DADADA
44 | skinparam SequenceGroupHeaderFontColor #000000
45 | skinparam BoxPadding 20
46 | skinparam ParticipantPadding 10
47 |
48 | skinparam AgentBackgroundColor White
49 | skinparam AgentBackgroundColor $blueFill
50 | skinparam AgentBorderColor #066DFA
51 | skinparam noteBorderColor FEF3BF
52 | skinparam SequenceBoxBorderColor F2F2F2
53 | skinparam shadowing false
54 | skinparam AgentBorderThickness 1
55 |
56 | skinparam NoteBackgroundColor FEFFDD
57 |
58 | skinparam FrameBackgroundColor $lightGray
59 | skinparam FrameBorderColor $lightGray
60 | skinparam FrameFontColor $darkGray
61 |
62 | skinparam ActivityBackgroundColor $blueFill
63 |
64 | skinparam StateBackgroundColor $blueFill
65 | skinparam StateBorderColor $blue
66 | skinparam StateStartColor $blue
67 | skinparam StateEndColor $blue
68 | skinparam StateFontSize 12
69 |
70 | skinparam ActivityBackgroundColor $blueFill
71 | skinparam ActivityBorderColor $blue
72 | skinparam ActivityEndColor $blue
73 | skinparam ActivityStartColor $blue
74 | skinparam ActivityDiamondBackgroundColor $lightGray
75 | skinparam ActivityDiamondBorderColor $blue
76 |
77 | skinparam PartitionBackgroundColor $lightGray
78 | skinparam PartitionBorderColor $darkGray
79 | skinparam PartitionFontColor $darkGray
80 |
81 | skinparam ClassAttributeFontColor Black
82 | skinparam ClassBorderColor $blue
83 | skinparam ClassBackgroundColor $blueFill
84 |
--------------------------------------------------------------------------------
/specifications/identity-trust-sts-api.yaml:
--------------------------------------------------------------------------------
1 | openapi: 3.0.1
2 | paths:
3 | /token:
4 | post:
5 | operationId: token
6 | requestBody:
7 | content:
8 | application/x-www-form-urlencoded:
9 | encoding:
10 | token:
11 | style: form
12 | audience:
13 | style: form
14 | bearer_access_scope:
15 | style: form
16 | client_secret:
17 | style: form
18 | grant_type:
19 | style: form
20 | schema:
21 | type: object
22 | properties:
23 | token:
24 | type: string
25 | description: VP access token to be added as a claim in the SI token
26 | audience:
27 | type: string
28 | description: Audience for the SI token
29 | bearer_access_scope:
30 | type: string
31 | description: Scope to be added in the VP access token
32 | client_id:
33 | type: string
34 | description: Id of the client requesting an SI token
35 | client_secret:
36 | type: string
37 | description: Secret of the client requesting an SI token
38 | grant_type:
39 | type: string
40 | description: "Type of grant: must be set to client_credentials"
41 | required:
42 | - audience
43 | - client_id
44 | - client_secret
45 | - grant_type
46 | responses:
47 | "200":
48 | content:
49 | application/json:
50 | schema:
51 | $ref: '#/components/schemas/StsTokenResponse'
52 | description: The Self-Issued ID token
53 | "400":
54 | content:
55 | application/json:
56 | schema:
57 | type: array
58 | items:
59 | $ref: '#/components/schemas/StsTokenErrorResponse'
60 | description: Invalid Request
61 | tags:
62 | - Secure Token Service Api
63 | components:
64 | schemas:
65 | StsTokenErrorResponse:
66 | type: object
67 | properties:
68 | error:
69 | type: string
70 | error_description:
71 | type: string
72 | StsTokenResponse:
73 | type: object
74 | properties:
75 | access_token:
76 | type: string
77 | expires_in:
78 | type: integer
79 | format: int64
80 | token_type:
81 | type: string
82 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/context/issuance/IssuanceContextTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.context.issuance;
16 |
17 | import jakarta.json.JsonObject;
18 | import org.eclipse.dcp.context.fixtures.AbstractJsonLdTest;
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.params.ParameterizedTest;
21 | import org.junit.jupiter.params.provider.ValueSource;
22 |
23 | import java.io.IOException;
24 |
25 | public class IssuanceContextTest extends AbstractJsonLdTest {
26 |
27 | @Test
28 | void verifyCredentialRequestMessage() {
29 | verifyRoundTrip("/issuance/example/credential-request-message.json", "/issuance/credential-request-message-schema.json");
30 | }
31 |
32 | @Test
33 | void verifyCredentialMessage() {
34 | verifyRoundTrip("/issuance/example/credential-message.json", "/issuance/credential-message-schema.json");
35 | }
36 |
37 | @Test
38 | void verifyCredentialMessageRejected() {
39 | verifyRoundTrip("/issuance/example/credential-message-rejected.json", "/issuance/credential-message-schema.json");
40 | }
41 |
42 | @Test
43 | void verifyCredentialOfferMessage() {
44 | verifyRoundTrip("/issuance/example/credential-offer-message.json", "/issuance/credential-offer-message-schema.json");
45 | }
46 |
47 | @Test
48 | void verifyCredentialObject() {
49 | verifyRoundTrip("/issuance/example/credential-object.json", "/issuance/credential-object-schema.json");
50 | }
51 |
52 | @Test
53 | void verifyIssuerMetadata() {
54 | verifyRoundTrip("/issuance/example/issuer-metadata.json", "/issuance/issuer-metadata-schema.json");
55 | }
56 |
57 | @Test
58 | void verifyCredentialStatus() {
59 | verifyRoundTrip("/issuance/example/credential-status.json", "/issuance/credential-status-schema.json");
60 | }
61 |
62 | @ParameterizedTest
63 | @ValueSource(strings = { "RECEIVED", "REJECTED", "ISSUED" })
64 | void verifyCredentialStatus_withStatus(String status) throws IOException {
65 | var msg = """
66 | {
67 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
68 | "type": "CredentialStatus",
69 | "issuerPid": "issuerPid",
70 | "holderPid": "holderPid",
71 | "status": "%s"
72 | }""".formatted(status);
73 |
74 | var message = mapper.readValue(msg, JsonObject.class);
75 | verifyRoundTrip(message, "/issuance/credential-status-schema.json");
76 | }
77 |
78 | }
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/CredentialStatusSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.params.ParameterizedTest;
21 | import org.junit.jupiter.params.provider.ValueSource;
22 |
23 | import static com.networknt.schema.InputFormat.JSON;
24 | import static org.assertj.core.api.Assertions.assertThat;
25 |
26 | public class CredentialStatusSchemaTest extends AbstractSchemaTest {
27 |
28 | private static final String CREDENTIAL_STATUS = """
29 | {
30 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
31 | "type": "CredentialStatus",
32 | "issuerPid": "issuerPid",
33 | "holderPid": "holderPid",
34 | "status": "%s"
35 | }""";
36 |
37 | private static final String INVALID_CREDENTIAL_STATUS = """
38 | {
39 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
40 | "type": "CredentialStatus"
41 | }""";
42 |
43 | private static final String INVALID_CREDENTIAL_STATUS_MESSAGE_NO_TYPE_AND_CONTEXT = """
44 | {
45 | "issuerPid": "issuerPid",
46 | "holderPid": "holderPid",
47 | "status": "RECEIVED"
48 | }""";
49 |
50 | @Test
51 | void verifySchema() {
52 | assertThat(schema.validate(CREDENTIAL_STATUS.formatted("INVALID_STATUS"), JSON))
53 | .extracting(this::errorExtractor)
54 | .containsExactly(error(null, ENUM));
55 | assertThat(schema.validate(INVALID_CREDENTIAL_STATUS, JSON))
56 | .extracting(this::errorExtractor)
57 | .containsExactly(error("issuerPid", REQUIRED), error("holderPid", REQUIRED), error("status", REQUIRED));
58 |
59 | assertThat(schema.validate(INVALID_CREDENTIAL_STATUS_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
60 | .hasSize(2)
61 | .extracting(this::errorExtractor)
62 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
63 | }
64 |
65 | @ParameterizedTest
66 | @ValueSource(strings = { "RECEIVED", "REJECTED", "ISSUED" })
67 | void verifySchemaStatus(String status) {
68 | assertThat(schema.validate(CREDENTIAL_STATUS.formatted(status), JSON)).isEmpty();
69 |
70 | }
71 |
72 | @BeforeEach
73 | void setUp() {
74 | setUp("/issuance/credential-status-schema.json");
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/CredentialOfferMessageSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 | import static org.eclipse.dcp.schema.issuance.CredentialObjectSchemaTest.CREDENTIAL_OBJECT;
24 |
25 | public class CredentialOfferMessageSchemaTest extends AbstractSchemaTest {
26 |
27 | private static final String CREDENTIAL_OFFER_MESSAGE = """
28 | {
29 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
30 | "type": "CredentialOfferMessage",
31 | "issuer": "issuer",
32 | "credentials": [%s]
33 | }""";
34 |
35 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_CREDENTIAL_ISSUER = """
36 | {
37 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
38 | "type": "CredentialOfferMessage",
39 | "credentials": [%s]
40 | }""";
41 |
42 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_CREDENTIALS = """
43 | {
44 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
45 | "type": "CredentialOfferMessage",
46 | "issuer": "issuer"
47 | }""";
48 |
49 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT = """
50 | {
51 | "issuer": "issuer",
52 | "credentials": [%s]
53 | }""";
54 |
55 | @Test
56 | void verifySchema() {
57 | assertThat(schema.validate(CREDENTIAL_OFFER_MESSAGE.formatted(CREDENTIAL_OBJECT), JSON)).isEmpty();
58 |
59 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_CREDENTIAL_ISSUER.formatted(CREDENTIAL_OBJECT), JSON))
60 | .extracting(this::errorExtractor)
61 | .containsExactly(error("issuer", REQUIRED));
62 |
63 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_CREDENTIALS, JSON))
64 | .extracting(this::errorExtractor)
65 | .containsExactly(error("credentials", REQUIRED));
66 |
67 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT.formatted(CREDENTIAL_OBJECT), JSON))
68 | .hasSize(2)
69 | .extracting(this::errorExtractor)
70 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
71 | }
72 |
73 | @BeforeEach
74 | void setUp() {
75 | setUp("/issuance/credential-offer-message-schema.json");
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/artifacts/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo. 1>&2
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
48 | echo. 1>&2
49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
50 | echo location of your Java installation. 1>&2
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo. 1>&2
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
62 | echo. 1>&2
63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
64 | echo location of your Java installation. 1>&2
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/IssuerMetadataSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 | import static org.eclipse.dcp.schema.issuance.CredentialObjectSchemaTest.CREDENTIAL_OBJECT;
24 |
25 | public class IssuerMetadataSchemaTest extends AbstractSchemaTest {
26 |
27 | public static final String ISSUER_METADATA = """
28 | {
29 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
30 | "type": "IssuerMetadata",
31 | "issuer": "did:web:issuer-url",
32 | "credentialsSupported": [%s]
33 | }""";
34 | public static final String CREDENTIAL_OBJECT_INCOMPLETE = """
35 | {
36 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
37 | "type": "CredentialObject",
38 | "credentialType": "VerifiableCredential",
39 | "offerReason": "reissue",
40 | "bindingMethods": [
41 | "did:web"
42 | ]
43 | }
44 | """;
45 | private static final String INVALID_ISSUER_METADATA = """
46 | {
47 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
48 | "type": "IssuerMetadata"
49 | }""";
50 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT = """
51 | {
52 | "issuer": "did:web:issuer-url",
53 | "credentialsSupported": [%s]
54 | }""";
55 |
56 | @Test
57 | void verifySchema() {
58 | assertThat(schema.validate(ISSUER_METADATA.formatted(CREDENTIAL_OBJECT), JSON)).isEmpty();
59 | }
60 |
61 | @Test
62 | void verifySchema_missingIssuerAndCredentialsSupported() {
63 | assertThat(schema.validate(INVALID_ISSUER_METADATA, JSON))
64 | .extracting(this::errorExtractor)
65 | .containsExactly(error("issuer", REQUIRED), error("credentialsSupported", REQUIRED));
66 |
67 | }
68 |
69 | @Test
70 | void verifySchema_credentialSupportedIsIncomplete() {
71 | assertThat(schema.validate(ISSUER_METADATA.formatted(CREDENTIAL_OBJECT_INCOMPLETE), JSON))
72 | .extracting(this::errorExtractor)
73 | .containsExactlyInAnyOrder(error("credentialSchema", REQUIRED), error("profile", REQUIRED));
74 | }
75 |
76 | @Test
77 | void verifySchema_missingTypeAndContext() {
78 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT.formatted(CREDENTIAL_OBJECT), JSON))
79 | .hasSize(2)
80 | .extracting(this::errorExtractor)
81 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
82 | }
83 |
84 | @BeforeEach
85 | void setUp() {
86 | setUp("/issuance/issuer-metadata-schema.json");
87 | }
88 |
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/specifications/dataspace.ecosystem.md:
--------------------------------------------------------------------------------
1 | # Dataspace Ecosystem Overview
2 |
3 | This section describes the core actors and systems in a dataspace ecosystem that are pertinent to this specification. It
4 | adheres to the model defined by the Dataspace Protocol [[dsp-base]]:
5 |
6 | - A Dataspace is a policy-based data sharing context between two or more entities.
7 | - The Dataspace Governance Authority is responsible for operational management of a [=dataspace=],
8 | including [=participant=] registration and designation of trust credential issuers.
9 | - A Participant is a member of the [=dataspace=]. Members MAY take on different roles, which are attested to
10 | by verifiable credentials.
11 | - A Participant Agent performs tasks such as publishing a catalog or engaging in data transfer. Note that a
12 | participant agent is a logical construct and does not necessarily correspond to a single runtime process.
13 | - An Identity Provider is a service that generates identity tokens used to verify the identity of a
14 | [=Participant Agent=]. Each [=participant=] will use their own identity provider to generate a self-signed identity
15 | token.
16 | - A Credential Issuer issues [=Verifiable Credentials=] used by [=participant agents=] to allow access to
17 | assets and verify usage control.
18 |
19 | ## Interrelation to the Dataspace Protocol
20 |
21 | The Dataspace Protocol (DSP) [[dsp-base]] is designed as a layered protocol, which is independent of the
22 | identity and trust system used. The Decentralized Claims Protocol fills this gap by providing such an orthogonal
23 | overlay for identity and trust in a decentralized manner.
24 |
25 | ## Systems
26 |
27 | ### Dataspace Governance Authority Systems
28 |
29 | Registration System
30 |
31 | The registration system is responsible for [=participant=] registration, onboarding, and management in a dataspace.
32 | The registration system is run by the [=Dataspace Governance Authority=] and is outside the scope of this specification.
33 |
34 | ### Participant Agent Systems
35 |
36 | [=Participants=] will run one or more agent systems that interact in the dataspace. These systems MAY offer data
37 | catalogs, perform data transfers, or provide application functionality. A [=participant=] MAY run the following
38 | identity-related agents. Note that this is a logical description and MAY not represent an actual deployment topology.
39 |
40 | Security Token Service (STS).
41 |
42 | The STS creates self-issued authorization tokens that contain identity claims used by [=participant agents=] under the
43 | control of the same [=participant=].
44 |
45 | Credential Service (CS)
46 |
47 | The CS manages [=Verifiable Credentials=]. This includes read and write endpoints for [=Verifiable Presentations=]
48 | and [=Verifiable Credentials=].
49 |
50 | DID Service (DIDS).
51 |
52 | The DIDS creates, signs, and publishes DID documents.
53 |
54 | ### Credential Issuer Systems
55 |
56 | Issuer Service (IS)
57 |
58 | The Issuer Service is run by a trust anchor and manages the lifecycle of [=Verifiable Credentials=] in a dataspace. A
59 | dataspace MAY contain multiple Issuer Services run by different trust anchors. The Issuer Service:
60 |
61 | - Issues [=Verifiable Credentials=] for dataspace [=participants=].
62 | - Manages revocation lists for [=Verifiable Credentials=] types it issues based
63 | on [[[vc-bitstring-status-list-20230427]]].
64 | - Provides cryptographic material used to verify [=Verifiable Presentations=] and [=Verifiable Credentials=].
65 |
--------------------------------------------------------------------------------
/WEBSITE.md:
--------------------------------------------------------------------------------
1 | ## Static Rendering and Web Deployment
2 |
3 | This repository contains the set of artifacts that make up the normative
4 | and non-normative sections of the Decentralized Claims Protocol. All artifacts are
5 | bundled by the [respec framework](https://www.respec.org) which takes care
6 | of rendering a static website.
7 |
8 | ### Conventions
9 |
10 | The following extensions to the basic markdown syntax are used in this
11 | specification project. Keep them handy and navigating the document will
12 | be easy.
13 |
14 | - Referencing an external specification document. [Respec Docs](https://respec.org/docs/#references-0)
15 | - with identifier inline `[[foreign-spec-id]]`
16 | - with the foreign spec's display name inline `[[[foreign-spec-id]]]`
17 | - referencing a particular section in a remote document works via ordinary markdown links. The reference has to be
18 | added to the `References` section manually (if it's not already there).
19 | - Defining terminology: A term is defined by wrapping it in
20 | `Defineable `. [Respec Docs](https://respec.org/docs/#definitions-and-linking)
21 | - Custom section IDs: If various sections have the same heading, they must be given a unique id manually via
22 | `{#my-custom-section-id}` that can then be used for referencing
23 | it. [Respec Docs](https://respec.org/docs/#example-specifying-a-custom-id-for-a-heading)
24 | - Referencing within the document. Please note that despite separation in multiple markdown files, there is only one
25 | html document. References to sections must be flat `(#section)` instead of path-based
26 | `../specifications/verifiable.presentation.protocol.md#presentation-flow`.
27 | - with the sections number and display name inline `[[[#my-section-id]]]`
28 | - If that's not desired, ordinary links work as well. `[my custom link](#my-section-id)`
29 | - referencing terminology: `[=Defineable=]`. This will work out of the box with Plurals such that `[=Definables=]`
30 | refers to the definition of `Defineable `.
31 | - Code blocks work natively like in markdown.
32 |
33 | ### Rendering in your IDE
34 |
35 | 1. Locally execute `mkdir resources` `cp -r ./artifacts/src/main/resources/* resources` from the repository root.
36 | 2. Open the `index.html` file.
37 | 3. Your IDE should have a feature to display html documents (either in your browser of choice or inline). Use that and
38 | you should always see the updated webpage when saving.
39 |
40 | ### Publishing versions
41 |
42 | When wanting to pin and publish a snapshot in time via a separate url-path, follow the appropriate steps listed below.
43 |
44 | #### Prep commits
45 |
46 | When the content is finished, a release requires a first commit with
47 |
48 | 1. a tag with the exact version string (like `v1.0-RC1`) on the release commit
49 | 2. to change the redirect in `.github/scripts/index.html` to point to latest release candidate
50 | 3. set the `respecConfig.publishDate` in `index.html` to a string like `"2025-02-27"`,`
51 | 4. set the `respecConfig.specStatus` in `index.html` to `base`
52 |
53 | In case of versions with a new namespace, additionally:
54 |
55 | 5. adjust the textual description of the context URI in the base spec
56 | 6. appended w3id referrals
57 |
58 | and then (independently of major/minor) a second commit
59 |
60 | 1. setting the specStatus config option to `unofficial` and
61 | 2. increase the spec version in the title of `index.html`
62 | 3. remove the release date
63 |
64 | #### Push and build
65 |
66 | - Open a PR with both commits. Wait for it to be merged.
67 | - Push the tag to origin/main on Github.
68 | - Rerun the actions.
69 |
70 | You should now see an additional endpoint at `https://eclipse-dataspace-dcp.github.io/decentralized-claims-protocol/my-version-tag/`.
71 |
--------------------------------------------------------------------------------
/specifications/dcp.profiles.md:
--------------------------------------------------------------------------------
1 | ## Profiles of the Decentralized Claims Protocol
2 |
3 | Different variations of the Verifiable Credentials Data Model, the revocation system, and proof stack
4 | complicate interoperability. Profiles of the DCP specification help
5 | narrow down those possibilities.
6 |
7 | This specification defines two profiles, which are referenced by an alias.
8 |
9 | ## DCP Profile Definitions
10 |
11 | | alias | VC Data Model | Revocation System | Proof Stack | Remarks |
12 | |-------------------|--------------------------------------------------------------|--------------------------------------------------------------------------|----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
13 | | `vc20-bssl/jwt` | [VC Data Model 2.0](https://www.w3.org/TR/vc-data-model-2.0) | [BitStringStatusList](https://www.w3.org/TR/vc-bitstring-status-list/) | Enveloped proofs [using JWT/JOSE](https://www.w3.org/TR/vc-jose-cose/#with-jose) | Ignore `ttl`, use `validUntil` (*). No JWE supported. The concrete signature algorithm is not specified, as implementors are expected to handle all reasonably well-known crypto algorithms like RSA, EC and EdDSA |
14 | | `vc11-sl2021/jwt` | [VC Data Model 1.1](https://www.w3.org/TR/vc-data-model) | [StatusList2021](https://www.w3.org/TR/2023/WD-vc-status-list-20230427/) | External proofs using JWT | No JWE supported. The concrete signature algorithm is not specified, as implementors are expected to handle all reasonably well-known crypto algorithms like RSA, EC and EdDSA |
15 |
16 | (*) In its current form, the BitStringStatusList credential data
17 | model [conflicts](https://www.w3.org/TR/vc-bitstring-status-list/#bitstringstatuslistcredential) with the VC DataModel
18 | 2.0, specifically regarding the validity period (`ttl` vs `validUntil`).
19 |
20 | ### Homogeneity requirement
21 |
22 | Verifiable Credentials MUST be _homogenous_. This means the
23 | same data model version and proof mechanism MUST be used for both credentials and presentations. For example, a
24 | verifiable credential secured with an _enveloped proof_ using
25 | JOSE ([VC Data Model 2.0](https://www.w3.org/TR/vc-jose-cose/#with-jose)) is enclosed in a verifiable presentation
26 | that is also secured with JWT/JOSE.
27 |
28 | Heterogeneous sets of credentials MUST be enclosed in multiple presentations such that each presentation only
29 | contains credentials of the same data model and proof mechanism.
30 |
31 | ## Profile Authoring Recommendations
32 |
33 | This non-normative section is intended to provide guidance to authors who want to define their own profile definition.
34 |
35 | At a minimum, the following profile aspects MUST be defined:
36 |
37 | - Verifiable Credential Data Model.
38 | - Revocation System. Specifies how the validity and expiration of Verifiable Credentials is checked.
39 | - Proof stack. Specifies how data integrity of the VC is to be provided.
40 |
41 | In addition, the profile MAY be further constrained, for example, by limiting the number of acceptable cryptographic
42 | algorithms.
43 |
44 | If possible, a single credential format SHOULD be used when defining a profile.
--------------------------------------------------------------------------------
/specifications/issuer-holder-verifier-model.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Verifiable Data Registry
4 | Maintains identifiers and schemas
5 | Verify identifiers and use schemas
6 |
7 |
8 | Verifier
9 | Verifies VCs
10 | Register identifiers and use schemas
11 |
12 |
13 | Holder
14 | Acquires and presents VCs
15 | Verify identifiers and use schemas
16 |
17 | Issue credentials
18 |
19 | Present credentials
20 |
21 |
22 | Issuer
23 | Issues VCs
24 |
25 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/presentation/PresentationResponseMessageSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.presentation;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 |
24 | public class PresentationResponseMessageSchemaTest extends AbstractSchemaTest {
25 |
26 | private static final String PRESENTATION_RESPONSE_MESSAGE = """
27 | {
28 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
29 | "type": "PresentationResponseMessage",
30 | "presentation": ["presentation1", "presentation2"]
31 | }""";
32 |
33 | private static final String PRESENTATION_RESPONSE_MESSAGE_WITH_OBJECT = """
34 | {
35 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
36 | "type": "PresentationResponseMessage",
37 | "presentation": ["presentation1", {"@id": "presentation2"}]
38 | }""";
39 |
40 | private static final String PRESENTATION_RESPONSE_MESSAGE_WITH_PRESENTATION_SUBMISSION = """
41 | {
42 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
43 | "type": "PresentationResponseMessage",
44 | "presentation": ["presentation1"],
45 | "presentationSubmission": {
46 | "id": "id",
47 | "definition_id": "definition_id",
48 | "descriptor_map": []
49 | }
50 | }""";
51 |
52 | private static final String INVALID_PRESENTATION_RESPONSE_MESSAGE_NO_PRESENTATION = """
53 | {
54 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
55 | "type": "PresentationResponseMessage"
56 | }""";
57 |
58 | private static final String INVALID_PRESENTATION_RESPONSE_MESSAGE_NO_TYPE_AND_CONTEXT = """
59 | {
60 | "presentation": ["presentation1", "presentation2"]
61 | }""";
62 |
63 | private static final String INVALID_PRESENTATION_RESPONSE_MESSAGE_EMPTY_PRESENTATION_SUBMISSION = """
64 | {
65 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
66 | "type": "PresentationResponseMessage",
67 | "presentation": ["presentation1"],
68 | "presentationSubmission": {
69 |
70 | }
71 | }""";
72 |
73 | @Test
74 | void verifySchema() {
75 | assertThat(schema.validate(PRESENTATION_RESPONSE_MESSAGE, JSON)).isEmpty();
76 | assertThat(schema.validate(PRESENTATION_RESPONSE_MESSAGE_WITH_OBJECT, JSON)).isEmpty();
77 | assertThat(schema.validate(PRESENTATION_RESPONSE_MESSAGE_WITH_PRESENTATION_SUBMISSION, JSON)).isEmpty();
78 | assertThat(schema.validate(INVALID_PRESENTATION_RESPONSE_MESSAGE_NO_PRESENTATION, JSON))
79 | .extracting(this::errorExtractor)
80 | .containsExactly(error("presentation", REQUIRED));
81 |
82 | assertThat(schema.validate(INVALID_PRESENTATION_RESPONSE_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
83 | .hasSize(2)
84 | .extracting(this::errorExtractor)
85 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
86 |
87 | assertThat(schema.validate(INVALID_PRESENTATION_RESPONSE_MESSAGE_EMPTY_PRESENTATION_SUBMISSION, JSON))
88 | .hasSize(3)
89 | .extracting(this::errorExtractor)
90 | .contains(error("id", REQUIRED), error("definition_id", REQUIRED), error("descriptor_map", REQUIRED));
91 |
92 | }
93 |
94 | @BeforeEach
95 | void setUp() {
96 | setUp("/presentation/presentation-response-message-schema.json");
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/pr_etiquette.md:
--------------------------------------------------------------------------------
1 | # Etiquette for pull requests
2 |
3 | Typically, changes to the specification documents should be made by
4 | the [editors](#the-designated-editors-as-of-sept-21-2023), as it is their duty to ensure consistency and proper
5 | linguistic properties. However, if you want to raise pull-requests of your own, please be sure to carefully read the
6 | following sections, and adhere to the rules stated therein. Failing to do so may result in the rejection of your PR.
7 |
8 | ## As an author
9 |
10 | Submitting pull requests in EDC should be done while adhering to a couple of simple rules.
11 |
12 | - Familiarize yourself with the contribution guidelines.
13 | - No surprise PRs please. Before you submit a PR, open a discussion or an issue outlining your planned work and give
14 | people time to comment. It may even be advisable to contact committers using the `@mention` feature. Unsolicited PRs
15 | may get ignored or rejected.
16 | - Don't argue basic principles ("Why don't we use X instead of Y", "how-about-ism")
17 | - Create your working branch in your fork of this repository, and create the PR against the upstream `main` branch
18 | - Create focused PRs: your work should be focused on one particular feature or bug. Do not create broad-scoped PRs that
19 | solve multiple issues as reviewers may reject those PR bombs outright.
20 | - Provide a clear description and motivation in the PR description in GitHub. This makes the reviewer's life much
21 | easier. It is also helpful to outline the broad changes that were made, e.g. "Changes the wording of XYZ-Entity:
22 | use `XYZ` instead of `ABC`".
23 | - All CI checks should be green, especially when your PR is in `"Ready for review"`
24 | - Mark PRs as `"Ready for review"` only when you're prepared to defend your work. By that time you have completed your
25 | work and shouldn't need to push any more commits other than to incorporate review comments.
26 | - Merge conflicts should be resolved by squashing all commits on the PR branch, rebasing onto `main` and
27 | force-pushing. Do this when your PR is ready to review.
28 | - If you require a reviewer's input while it's still in draft, please contact the designated reviewer using
29 | the `@mention` feature and let them know what you'd like them to look at.
30 | - Request a review from one of the committers. Requesting a review from anyone else is still possible, and
31 | sometimes may be advisable, but only committers can merge PRs, so be sure to include them early on.
32 | - Re-request reviews after all remarks have been adopted. This helps reviewers track their work in GitHub.
33 | - If you disagree with a committer's remarks, feel free to object and argue, but if no agreement is reached, you'll have
34 | to either accept the decision or withdraw your PR.
35 | - Be civil and objective. No foul language, insulting or otherwise abusive language will be tolerated.
36 | - The PR titles must follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
37 | - The title must follow the format as `(): `.
38 | `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test` are allowed for
39 | the ``.
40 | - The length must be kept under 80 characters.
41 |
42 | ## As a reviewer
43 |
44 | - Please complete reviews within two business days or delegate to another committer, removing yourself as a reviewer.
45 | - If you have been requested as reviewer, but cannot do the review for any reason (lack of time or expertise in a
46 | particular area, etc.) please comment that in the PR and remove yourself as a reviewer, suggesting a stand-in.
47 | - Be pedantic. This is a normative document, so wording, terminology and general formulation are important.
48 | - Don't get dragged into basic arguments ("how-about-ism")
49 | - Use the `suggestion` feature of GitHub for small/simple changes.
50 | - The following could serve you as a review checklist:
51 | - writing style, wording
52 | - simplicity and "uncluttered-ness" of the text
53 | - overall focus of the PR
54 | - Don't just wave through any PR. Please take the time to look at them carefully.
55 | - Be civil and objective. No foul language, insulting or otherwise abusive language will be tolerated. The goal is to
56 | _encourage_ contributions.
57 |
58 | ## The designated editors (as of Sept 21, 2023)
59 |
60 | - Jim Marino (@jimmarino)
61 |
62 | ## Responsible committers
63 |
64 | [Who's involved](https://projects.eclipse.org/projects/technology.dataspace-dcp/who)
65 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/CredentialObjectSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 |
24 | public class CredentialObjectSchemaTest extends AbstractSchemaTest {
25 |
26 | public static final String CREDENTIAL_OBJECT = """
27 | {
28 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
29 | "type": "CredentialObject",
30 | "credentialType": "VerifiableCredential",
31 | "credentialSchema": "https://example.com/credentials/credentialSchema",
32 | "offerReason": "reissue",
33 | "bindingMethods": [
34 | "did:web"
35 | ],
36 | "profile": "vc20-bssl/jwt",
37 | "issuancePolicy": {
38 | "id": "Scalable trust example",
39 | "input_descriptors": [
40 | {
41 | "id": "pd-id",
42 | "constraints": {
43 | "fields": [
44 | {
45 | "path": [
46 | "$.holderIdentifier"
47 | ],
48 | "filter": {
49 | "type": "string",
50 | "pattern": "^BPN[LS][a-zA-Z0-9]{12}$"
51 | }
52 | }
53 | ]
54 | }
55 | }
56 | ]
57 | }
58 | }
59 | """;
60 |
61 | private static final String INVALID_CREDENTIAL_OBJECT = """
62 | {
63 | "type": "CredentialObject"
64 | }""";
65 |
66 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT = """
67 | {
68 | "id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1",
69 | "credentialType": "VerifiableCredential",
70 | "offerReason": "reissue",
71 | "bindingMethods": [
72 | "did:web"
73 | ],
74 | "profile":"vc20-bssl/jwt",
75 | "issuancePolicy": {
76 | "id": "Scalable trust example",
77 | "input_descriptors": [
78 | {
79 | "id": "pd-id",
80 | "constraints": {
81 | "fields": [
82 | {
83 | "path": [
84 | "$.vc.type"
85 | ],
86 | "filter": {
87 | "type": "string",
88 | "pattern": "^AttestationCredential$"
89 | }
90 | }
91 | ]
92 | }
93 | }
94 | ]
95 | }
96 | }""";
97 |
98 | @Test
99 | void verifySchema() {
100 | assertThat(schema.validate(CREDENTIAL_OBJECT, JSON)).isEmpty();
101 | }
102 |
103 | @Test
104 | void verifySchema_missingRequiredFields() {
105 | assertThat(schema.validate(INVALID_CREDENTIAL_OBJECT, JSON))
106 | .extracting(this::errorExtractor)
107 | .containsExactly(
108 | error("id", REQUIRED));
109 | }
110 |
111 | @Test
112 | void verifySchema_missingTypeAndContext() {
113 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
114 | .hasSize(1)
115 | .extracting(this::errorExtractor)
116 | .contains(error("type", REQUIRED));
117 |
118 | }
119 |
120 | @BeforeEach
121 | void setUp() {
122 | setUp("/issuance/credential-object-schema.json");
123 | }
124 |
125 |
126 | }
127 |
--------------------------------------------------------------------------------
/artifacts/src/main/resources/context/dcp.jsonld:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "@version": 1.1,
4 | "@protected": true,
5 | "dcp": "https://w3id.org/dspace-dcp/v1.0/",
6 | "cred": "https://www.w3.org/2018/credentials#",
7 | "xsd": "http://www.w3.org/2001/XMLSchema#",
8 | "id": "@id",
9 | "type": "@type",
10 | "CredentialContainer": {
11 | "@id": "dcp:CredentialContainer",
12 | "@context": {
13 | "payload": {
14 | "@id": "dcp:payload",
15 | "@type": "xsd:string"
16 | }
17 | }
18 | },
19 | "CredentialMessage": {
20 | "@id": "dcp:CredentialMessage",
21 | "@context": {
22 | "credentials": {
23 | "@id": "dcp:credentials",
24 | "@container": "@set",
25 | "@type": "@json"
26 | },
27 | "issuerPid": {
28 | "@id": "dcp:issuerPid",
29 | "@type": "@id"
30 | },
31 | "holderPid": {
32 | "@id": "dcp:holderPid",
33 | "@type": "@id"
34 | },
35 | "status": {
36 | "@id": "dcp:status",
37 | "@type": "@id"
38 | },
39 | "rejectionReason": {
40 | "@id": "dcp:rejectionReason"
41 | }
42 | }
43 | },
44 | "CredentialObject": {
45 | "@id": "dcp:CredentialObject",
46 | "@context": {
47 | "credentialType": {
48 | "@id": "dcp:credentialType"
49 | },
50 | "credentialSchema": {
51 | "@id": "dcp:credentialSchema"
52 | },
53 | "offerReason": {
54 | "@id": "dcp:offerReason",
55 | "@type": "xsd:string"
56 | },
57 | "bindingMethods": {
58 | "@id": "dcp:bindingMethods",
59 | "@type": "xsd:string",
60 | "@container": "@set"
61 | },
62 | "profile": {
63 | "@id": "dcp:profile",
64 | "@type": "xsd:string"
65 | },
66 | "issuancePolicy": {
67 | "@id": "dcp:issuancePolicy",
68 | "@type": "@json"
69 | }
70 | }
71 | },
72 | "CredentialOfferMessage": {
73 | "@id": "dcp:CredentialOfferMessage",
74 | "@context": {
75 | "issuer": {
76 | "@id": "cred:issuer",
77 | "@type": "@id"
78 | },
79 | "credentials": {
80 | "@id": "dcp:credentials",
81 | "@container": "@set"
82 | }
83 | }
84 | },
85 | "CredentialRequestMessage": {
86 | "@id": "dcp:CredentialRequestMessage",
87 | "@context": {
88 | "holderPid": {
89 | "@id": "dcp:holderPid",
90 | "@type": "@id"
91 | },
92 | "credentials": {
93 | "@id": "dcp:credentials",
94 | "@type": "@json"
95 | }
96 | }
97 | },
98 | "CredentialService": "dcp:CredentialService",
99 | "CredentialStatus": {
100 | "@id": "dcp:CredentialStatus",
101 | "@context": {
102 | "holderPid": {
103 | "@id": "dcp:holderPid",
104 | "@type": "@id"
105 | },
106 | "issuerPid": {
107 | "@id": "dcp:issuerPid",
108 | "@type": "@id"
109 | },
110 | "status": {
111 | "@id": "dcp:status",
112 | "@type": "@vocab"
113 | },
114 | "RECEIVED": "dcp:RECEIVED",
115 | "REJECTED": "dcp:REJECTED",
116 | "ISSUED": "dcp:ISSUED"
117 | }
118 | },
119 | "IssuerMetadata": {
120 | "@id": "dcp:IssuerMetadata",
121 | "@context": {
122 | "issuer": {
123 | "@id": "cred:issuer",
124 | "@type": "@id"
125 | },
126 | "credentialsSupported": {
127 | "@id": "dcp:credentialsSupported",
128 | "@container": "@set"
129 | }
130 | }
131 | },
132 | "IssuerService": "dcp:IssuerService",
133 | "PresentationQueryMessage": {
134 | "@id": "dcp:PresentationQueryMessage",
135 | "@context": {
136 | "presentationDefinition": {
137 | "@id": "dcp:presentationDefinition",
138 | "@type": "@json"
139 | },
140 | "scope": {
141 | "@id": "dcp:scope",
142 | "@type": "xsd:string",
143 | "@container": "@set"
144 | }
145 | }
146 | },
147 | "PresentationResponseMessage": {
148 | "@id": "dcp:PresentationResponseMessage",
149 | "@context": {
150 | "presentation": {
151 | "@id": "dcp:presentation",
152 | "@container": "@set",
153 | "@type": "@json"
154 | },
155 | "presentationSubmission": {
156 | "@id": "dcp:presentationSubmission",
157 | "@type": "@json"
158 | }
159 | }
160 | }
161 | }
162 | }
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/CredentialRequestMessageSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 |
24 | public class CredentialRequestMessageSchemaTest extends AbstractSchemaTest {
25 |
26 | private static final String CREDENTIAL_REQUEST_MESSAGE = """
27 | {
28 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
29 | "type": "CredentialRequestMessage",
30 | "holderPid": "holderPid",
31 | "credentials": [
32 | {"id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1" },
33 | {"id": "c0f81e68-6d35-4f9d-bc04-51e511b2e46c" }
34 | ]
35 | }""";
36 |
37 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_HOLDER_REQUEST_ID = """
38 | {
39 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
40 | "type": "CredentialRequestMessage",
41 | "credentials": [
42 | {"id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1" },
43 | {"id": "c0f81e68-6d35-4f9d-bc04-51e511b2e46c" }
44 | ]
45 | }""";
46 |
47 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_ID_NOT_STRING = """
48 | {
49 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
50 | "type": "CredentialRequestMessage",
51 | "holderPid": "holderPid",
52 | "credentials": [
53 | { "id": 42069 },
54 | { "id": 4711 }
55 | ]
56 | }""";
57 |
58 |
59 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_EMPTY_ARRAY = """
60 | {
61 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
62 | "type": "CredentialRequestMessage",
63 | "holderPid": "holderPid",
64 | "credentials": [
65 | ]
66 | }""";
67 |
68 | private static final String INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT = """
69 | {
70 | "holderPid": "holderPid",
71 | "credentials": [
72 | {"id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1" },
73 | {"id": "c0f81e68-6d35-4f9d-bc04-51e511b2e46c" }
74 | ]
75 | }""";
76 |
77 | private static final String CREDENTIAL_REQUEST_MESSAGE_NO_FORMAT = """
78 | {
79 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
80 | "type": "CredentialRequestMessage",
81 | "holderPid": "holderPid",
82 | "credentials": [
83 | {"id": "d5c77b0e-7f4e-4fd5-8c5f-28b5fc3f96d1" },
84 | {"id": "c0f81e68-6d35-4f9d-bc04-51e511b2e46c" }
85 | ]
86 | }""";
87 |
88 |
89 | @Test
90 | void verifySchema() {
91 | assertThat(schema.validate(CREDENTIAL_REQUEST_MESSAGE, JSON)).isEmpty();
92 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_EMPTY_ARRAY, JSON))
93 | .isEmpty();
94 |
95 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_HOLDER_REQUEST_ID, JSON))
96 | .extracting(this::errorExtractor)
97 | .containsExactly(error("holderPid", REQUIRED));
98 |
99 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_ID_NOT_STRING, JSON))
100 | .extracting(this::errorExtractor)
101 | .containsExactly(error(null, TYPE), error(null, TYPE));
102 |
103 | assertThat(schema.validate(INVALID_CREDENTIAL_REQUEST_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
104 | .hasSize(2)
105 | .extracting(this::errorExtractor)
106 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
107 |
108 | }
109 |
110 | @BeforeEach
111 | void setUp() {
112 | setUp("/issuance/credential-request-message-schema.json");
113 | }
114 |
115 |
116 | }
117 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/presentation/PresentationQueryMessageSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.presentation;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 |
24 | public class PresentationQueryMessageSchemaTest extends AbstractSchemaTest {
25 |
26 | private static final String PRESENTATION_QUERY_MESSAGE = """
27 | {
28 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
29 | "type": "PresentationQueryMessage",
30 | "scope": ["scope1", "scope2"]
31 | }""";
32 |
33 | private static final String PRESENTATION_QUERY_MESSAGE_WITH_PRESENTATION_DEF = """
34 | {
35 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
36 | "type": "PresentationQueryMessage",
37 | "presentationDefinition": {
38 | "id": "presentation1",
39 | "input_descriptors": [
40 | {
41 | "id": "organization credential",
42 | "format": {
43 | "ldp_vc": {
44 | "proof_type": [
45 | "Ed25519Signature2018"
46 | ]
47 | }
48 | },
49 | "constraints": {
50 | "fields": [
51 | {
52 | "path": [
53 | "$.type"
54 | ],
55 | "filter": {
56 | "type": "string",
57 | "pattern": "OrganizationCredential"
58 | }
59 | }
60 | ]
61 | }
62 | }
63 | ]
64 | }
65 | }""";
66 |
67 | private static final String INVALID_PRESENTATION_QUERY_MESSAGE_NO_SCOPE = """
68 | {
69 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
70 | "type": "PresentationQueryMessage"
71 | }""";
72 |
73 | private static final String INVALID_PRESENTATION_QUERY_MESSAGE_EMPTY_SCOPE = """
74 | {
75 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
76 | "type": "PresentationQueryMessage",
77 | "scope": []
78 | }""";
79 |
80 |
81 | private static final String INVALID_PRESENTATION_QUERY_MESSAGE_NO_TYPE_AND_CONTEXT = """
82 | {
83 | "scope": ["scope1", "scope2"]
84 | }""";
85 |
86 | @Test
87 | void verifySchema() {
88 | assertThat(schema.validate(PRESENTATION_QUERY_MESSAGE, JSON)).isEmpty();
89 | }
90 |
91 | @Test
92 | void verifySchemaWithPresentationDefinition() {
93 | assertThat(schema.validate(PRESENTATION_QUERY_MESSAGE_WITH_PRESENTATION_DEF, JSON)).isEmpty();
94 | }
95 |
96 | @Test
97 | void verifySchema_withNoTypeAndContext() {
98 | assertThat(schema.validate(INVALID_PRESENTATION_QUERY_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
99 | .hasSize(2)
100 | .extracting(this::errorExtractor)
101 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
102 | }
103 |
104 | @Test
105 | void verifySchema_withEmptyScope() {
106 | assertThat(schema.validate(INVALID_PRESENTATION_QUERY_MESSAGE_EMPTY_SCOPE, JSON))
107 | .hasSize(1)
108 | .anyMatch(msg -> msg.getInstanceLocation().toString().endsWith("scope") &&
109 | msg.getType().equalsIgnoreCase("minItems"));
110 | }
111 |
112 | @Test
113 | void verifySchema_withNoScope() {
114 | assertThat(schema.validate(INVALID_PRESENTATION_QUERY_MESSAGE_NO_SCOPE, JSON))
115 | .extracting(this::errorExtractor)
116 | .contains(error("scope", REQUIRED), error("presentationDefinition", REQUIRED));
117 | }
118 |
119 | @BeforeEach
120 | void setUp() {
121 | setUp("/presentation/presentation-query-message-schema.json");
122 | }
123 |
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/context/fixtures/AbstractJsonLdTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.context.fixtures;
16 |
17 | import com.apicatalog.jsonld.JsonLdError;
18 | import com.apicatalog.jsonld.JsonLdOptions;
19 | import com.apicatalog.jsonld.document.Document;
20 | import com.apicatalog.jsonld.document.JsonDocument;
21 | import com.apicatalog.jsonld.loader.DocumentLoader;
22 | import com.apicatalog.jsonld.loader.DocumentLoaderOptions;
23 | import com.fasterxml.jackson.databind.JsonNode;
24 | import com.fasterxml.jackson.databind.ObjectMapper;
25 | import com.fasterxml.jackson.datatype.jsonp.JSONPModule;
26 | import com.networknt.schema.JsonSchemaFactory;
27 | import com.networknt.schema.SchemaLocation;
28 | import jakarta.json.Json;
29 | import jakarta.json.JsonObject;
30 | import jakarta.json.JsonStructure;
31 | import org.junit.jupiter.api.BeforeEach;
32 |
33 | import java.io.IOException;
34 | import java.net.URI;
35 | import java.util.HashMap;
36 | import java.util.Map;
37 |
38 | import static com.apicatalog.jsonld.JsonLd.compact;
39 | import static com.apicatalog.jsonld.JsonLd.expand;
40 | import static com.apicatalog.jsonld.lang.Keywords.CONTEXT;
41 | import static com.networknt.schema.SpecVersion.VersionFlag.V202012;
42 | import static java.lang.String.format;
43 | import static org.assertj.core.api.Assertions.assertThat;
44 | import static org.eclipse.dcp.schema.SchemaConstants.DCP_CONTEXT;
45 | import static org.eclipse.dcp.schema.SchemaConstants.DCP_PREFIX;
46 | import static org.eclipse.dcp.schema.fixtures.AbstractSchemaTest.PRESENTATION_EXCHANGE_PREFIX;
47 |
48 | /**
49 | * Base class for Json-Ld expansion and compaction tests.
50 | */
51 | public abstract class AbstractJsonLdTest {
52 | private static final String CLASSPATH_SCHEMA = "classpath:/";
53 | private static final String CONTEXT_REFERENCE = format("{\"@context\": [\"%s\"]}", DCP_CONTEXT);
54 | private final Map contextMap = Map.of(
55 | DCP_CONTEXT, "/context/dcp.jsonld",
56 | "https://www.w3.org/ns/odrl.jsonld", "/context/odrl.jsonld"
57 | );
58 | protected ObjectMapper mapper;
59 | protected JsonStructure compactionContext;
60 | protected JsonLdOptions options;
61 |
62 | @BeforeEach
63 | void setUp() {
64 | mapper = new ObjectMapper();
65 | mapper.registerModule(new JSONPModule());
66 |
67 | Map cache = new HashMap<>();
68 |
69 | contextMap.forEach((key, value) -> {
70 | try (var stream = getClass().getResourceAsStream(value)) {
71 | var context = mapper.readValue(stream, JsonObject.class);
72 | cache.put(key, JsonDocument.of(context));
73 | } catch (IOException e) {
74 | throw new RuntimeException(e);
75 | }
76 | });
77 | try {
78 | var documentLoader = new LocalDocumentLoader(cache);
79 | compactionContext = mapper.readValue(CONTEXT_REFERENCE, JsonStructure.class);
80 | options = new JsonLdOptions();
81 | options.setDocumentLoader(documentLoader);
82 | } catch (IOException e) {
83 | throw new RuntimeException(e);
84 | }
85 |
86 | }
87 |
88 | protected void verifyRoundTrip(String jsonFile, String schemaFile) {
89 | try {
90 | var stream = getClass().getResourceAsStream(jsonFile);
91 | var message = mapper.readValue(stream, JsonObject.class);
92 | verifyRoundTrip(message, schemaFile);
93 | } catch (IOException e) {
94 | throw new RuntimeException(e);
95 | }
96 | }
97 |
98 | protected void verifyRoundTrip(JsonObject message, String schemaFile) {
99 | try {
100 | var schemaFactory = JsonSchemaFactory.getInstance(V202012, builder ->
101 | builder.schemaMappers(schemaMappers -> schemaMappers.mapPrefix(DCP_PREFIX, CLASSPATH_SCHEMA)
102 | .mapPrefix(PRESENTATION_EXCHANGE_PREFIX, CLASSPATH_SCHEMA))
103 | );
104 | var schema = schemaFactory.getSchema(SchemaLocation.of(DCP_PREFIX + schemaFile));
105 | var resultExAnte = schema.validate(mapper.convertValue(message, JsonNode.class));
106 | assertThat(resultExAnte.isEmpty()).describedAs(String.join(", ", resultExAnte.stream().map(Object::toString).toList())).isTrue();
107 |
108 |
109 | var context = Json.createObjectBuilder().add(CONTEXT, message.get(CONTEXT)).build();
110 | var expanded = expand(JsonDocument.of(message)).options(options).get();
111 | var compacted = compact(JsonDocument.of(expanded), JsonDocument.of(context)).options(options).get();
112 |
113 |
114 | var resultExPost = schema.validate(mapper.convertValue(compacted, JsonNode.class));
115 | assertThat(resultExPost.isEmpty()).describedAs(String.join(", ", resultExPost.stream().map(Object::toString).toList())).isTrue();
116 | assertThat(compacted).isEqualTo(message);
117 | } catch (JsonLdError e) {
118 | throw new RuntimeException(e);
119 | }
120 | }
121 |
122 | private static class LocalDocumentLoader implements DocumentLoader {
123 | private final Map contexts = new HashMap<>();
124 |
125 | LocalDocumentLoader(Map contexts) {
126 | this.contexts.putAll(contexts);
127 | }
128 |
129 | @Override
130 | public Document loadDocument(URI url, DocumentLoaderOptions options) {
131 | return contexts.get(url.toString());
132 | }
133 | }
134 | }
--------------------------------------------------------------------------------
/artifacts/src/test/java/org/eclipse/dcp/schema/issuance/CredentialMessageSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2024 Metaform Systems, Inc.
3 | *
4 | * This program and the accompanying materials are made available under the
5 | * terms of the Apache License, Version 2.0 which is available at
6 | * https://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * SPDX-License-Identifier: Apache-2.0
9 | *
10 | * Contributors:
11 | * Metaform Systems, Inc. - initial API and implementation
12 | *
13 | */
14 |
15 | package org.eclipse.dcp.schema.issuance;
16 |
17 | import org.eclipse.dcp.schema.fixtures.AbstractSchemaTest;
18 | import org.junit.jupiter.api.BeforeEach;
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static com.networknt.schema.InputFormat.JSON;
22 | import static org.assertj.core.api.Assertions.assertThat;
23 |
24 | public class CredentialMessageSchemaTest extends AbstractSchemaTest {
25 |
26 | private static final String CREDENTIAL_MESSAGE_MESSAGE = """
27 | {
28 | "@context": [
29 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
30 | ],
31 | "type": "CredentialMessage",
32 | "credentials": [
33 | {
34 | "credentialType": "MembershipCredential",
35 | "payload": "",
36 | "format": "jwt"
37 | },
38 | {
39 | "credentialType": "OrganizationCredential",
40 | "payload": "",
41 | "format": "json-ld"
42 | }
43 | ],
44 | "status": "ISSUED",
45 | "issuerPid": "issuerPid",
46 | "holderPid": "holderPid"
47 | }""";
48 |
49 | private static final String CREDENTIAL_MESSAGE_MESSAGE_WRONG_STATUS = """
50 | {
51 | "@context": [
52 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
53 | ],
54 | "type": "CredentialMessage",
55 | "credentials": [
56 | {
57 | "credentialType": "MembershipCredential",
58 | "payload": "",
59 | "format": "jwt"
60 | },
61 | {
62 | "credentialType": "OrganizationCredential",
63 | "payload": "",
64 | "format": "json-ld"
65 | }
66 | ],
67 | "status": "INVALID",
68 | "issuerPid": "issuerPid",
69 | "holderPid": "holderPid"
70 | }""";
71 |
72 | private static final String CREDENTIAL_MESSAGE_MESSAGE_REJECTION = """
73 | {
74 | "@context": [
75 | "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"
76 | ],
77 | "type": "CredentialMessage",
78 | "status": "REJECTED",
79 | "rejectionReason": "some rejection reason",
80 | "issuerPid": "issuerPid",
81 | "holderPid": "holderPid"
82 | }""";
83 |
84 | private static final String INVALID_CREDENTIAL_MESSAGE = """
85 | {
86 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
87 | "type": "CredentialMessage",
88 | "status": "ISSUED"
89 | }""";
90 |
91 | private static final String INVALID_CREDENTIAL_MESSAGE_INVALID_CREDENTIAL_CONTAINER = """
92 | {
93 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
94 | "type": "CredentialMessage",
95 | "credentials": [
96 | {
97 | "credentialType": "MembershipCredential",
98 | "format": "jwt"
99 | }
100 | ],
101 | "status": "ISSUED",
102 | "issuerPid": "issuerPid",
103 | "holderPid": "holderPid"
104 | }""";
105 |
106 | private static final String INVALID_CREDENTIAL_MESSAGE_NO_STATUS = """
107 | {
108 | "@context": ["https://w3id.org/dspace-dcp/v1.0/dcp.jsonld"],
109 | "type": "CredentialMessage",
110 | "credentials": [
111 | {
112 | "credentialType": "OrganizationCredential",
113 | "payload": "",
114 | "format": "json-ld"
115 | }
116 | ],
117 | "issuerPid": "issuerPid",
118 | "holderPid": "holderPid"
119 | }""";
120 |
121 |
122 | private static final String INVALID_CREDENTIAL_MESSAGE_NO_TYPE_AND_CONTEXT = """
123 | {
124 | "credentials": [
125 | {
126 | "credentialType": "MembershipCredential",
127 | "payload": "",
128 | "format": "jwt"
129 | }
130 | ],
131 | "status": "ISSUED",
132 | "issuerPid": "issuerPid",
133 | "holderPid": "holderPid"
134 | }""";
135 |
136 | @Test
137 | void verifySchema() {
138 | assertThat(schema.validate(CREDENTIAL_MESSAGE_MESSAGE, JSON)).isEmpty();
139 | assertThat(schema.validate(CREDENTIAL_MESSAGE_MESSAGE_REJECTION, JSON)).isEmpty();
140 | assertThat(schema.validate(INVALID_CREDENTIAL_MESSAGE, JSON))
141 | .extracting(this::errorExtractor)
142 | .containsExactly(error("issuerPid", REQUIRED));
143 |
144 | assertThat(schema.validate(INVALID_CREDENTIAL_MESSAGE_INVALID_CREDENTIAL_CONTAINER, JSON))
145 | .extracting(this::errorExtractor)
146 | .containsExactly(error("payload", REQUIRED));
147 |
148 | assertThat(schema.validate(INVALID_CREDENTIAL_MESSAGE_NO_TYPE_AND_CONTEXT, JSON))
149 | .hasSize(2)
150 | .extracting(this::errorExtractor)
151 | .contains(error("type", REQUIRED), error("@context", REQUIRED));
152 |
153 | assertThat(schema.validate(INVALID_CREDENTIAL_MESSAGE_NO_STATUS, JSON))
154 | .hasSize(1)
155 | .extracting(this::errorExtractor)
156 | .contains(error("status", REQUIRED));
157 |
158 | assertThat(schema.validate(CREDENTIAL_MESSAGE_MESSAGE_WRONG_STATUS, JSON))
159 | .hasSize(1)
160 | .extracting(this::errorExtractor)
161 | .contains(error(null, ENUM)); // for some reason the property is `null` on enum validation errors
162 | }
163 |
164 | @BeforeEach
165 | void setUp() {
166 | setUp("/issuance/credential-message-schema.json");
167 | }
168 |
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
132 | Eclipse Decentralized Claims Protocol v1.0
133 |
134 |
135 |
136 | This document is licensed under The Apache License,
137 | Version 2.0 . Copyright © 2025 The Eclipse Foundation AISBL
138 |
139 | Eclipse Decentralized Claims Protocol v1.0
140 |
141 |
142 | Dataspaces require the ability to communicate participant identities and credentials to secure data access. This
143 | specification defines a set of protocols for asserting participant identities, issuing verifiable credentials,
144 | and presenting verifiable credentials using a decentralized architecture for verification and trust.
145 |
146 |
147 |
148 | Status of This Document
149 |
150 | This version (v1.0) of the Decentralized Claims Protocol specification is a release of the specification and
151 | considered to be stable. Further changes shall not affect conformity. All changes made to the specification can
152 | be reviewed in the GitHub repository .
153 | This specification is affiliated with the Eclipse Dataspace Working Group .
154 |
155 |
156 |
157 |
159 |
160 |
162 |
163 |
165 |
166 |
168 |
169 |
171 |
172 |
174 |
175 |
176 |
177 |
179 |
180 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/specifications/base.protocol.md:
--------------------------------------------------------------------------------
1 | # Base Concepts {#identity-protocol-base}
2 |
3 | This section defines the core identity concepts used by the current specification.
4 |
5 | ## Decentralization
6 |
7 | Decentralization is achieved in the following ways:
8 |
9 | - **Self-Issued ID Tokens** - Each [=participant=] is responsible for creating and cryptographically signing its own
10 | identity tokens. A central identity provider is therefore not required, eliminating a potential source of network
11 | failure.
12 | - **Participant Verifiable Credential and Cryptographic Material Management** - Each [=participant=] is responsible for
13 | storing [=Verifiable Credentials=] and presenting them as [=Verifiable Presentations=]. [=Participant=] are also
14 | responsible for storing and making their cryptographic material available to [=Verifiers=]. This specification defines
15 | how [=Verifiable Credentials=] are presented and verified without the need for a third-party verification service.
16 | - **Multiple Trust Anchors** - [=Participant=] [=Verifiable Credentials=] are signed by a third-party [=issuer=] acting
17 | as a trust anchor using a cryptographic proof. This specification allows for multiple trust anchors in a dataspace.
18 |
19 | ## Identities
20 |
21 | The Dataspace Protocol specification mandates that all participants have a stable identifier (Participant ID). This
22 | specification prescribes the Participant ID MUST be a [=DID=].
23 |
24 | ## Self-Issued ID Tokens
25 |
26 | [=Participants=] use a Self-Issued ID Token to authenticate themselves and present self-attested claims to a
27 | [=Verifier=]. A Self-Issued ID Token is represented as a JSON Web Token [[rfc7519]] signed with a private key under the
28 | participant's control.
29 |
30 | The following claims MUST be included in the Self-Issued ID Token:
31 |
32 | - The `iss` and `sub` claims MUST be equal and set to the bearer's (participant's) [=DID=].
33 | - The `aud` MUST be set to the [=Verifier=] [=DID=].
34 | - The `jti` claim MUST be used to mitigate against replay attacks.
35 | - The `exp` claim MUST be used to express the expiration time on or after which the ID Token MUST NOT be accepted by the
36 | [=verifier=]. Implementers MAY provide for some leeway to account for clock skew. Its value is a JSON [rfc8259] number
37 | representing the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time.
38 | - The `iat` claim MUST be used to specify the time the JWT was issued. Its value is a JSON number representing the
39 | number of seconds from 1970-01-01T00:00:00Z as measured in UTC.
40 |
41 | ### Verifiable Presentation Access Token
42 |
43 | A Self-Issued ID Token MAY contain an access token as a `token` claim that can be used by the [=Verifier=] to
44 | obtain [=Verifiable Presentations=] from the participant's [=Credential Service=]. The format of the `token` is
45 | implementation-specific and therefore SHOULD be treated as an opaque string by the [=Verifier=].
46 |
47 | ### Obtaining Self-Issued ID Tokens
48 |
49 | _This section is non-normative._
50 |
51 | How a Self-Issued ID token is obtained from a [=Secure Token Service=] is implementation-specific. An [=STS=] MAY
52 | support a
53 | variety of APIs, including OAuth 2.
54 |
55 | #### Using the OAuth 2 Client Credential Grant
56 |
57 | A Self-Issued ID Token MAY be obtained by executing a Client Credential Grant as defined in [[[?rfc6749]]]
58 | against a [=Secure Token Service=] endpoint. How the [=participant agent=] obtains the [=STS=] endpoint address is
59 | implementation-specific and beyond the scope of this specification.
60 |
61 | If an `token` is REQUIRED to be included in the Self Issued ID token, the [=participant agent=] will need to request
62 | scopes for the access token. This is dependent on the API used to obtain the Self-Issued ID Token. An [=STS=]
63 | implementation MAY use endpoint parameters as defined in the [[[?rfc6749]]] to convey metadata necessary for the
64 | creation of the `token` claim. In this case, the Self-Issued ID Token request MAY contain a `bearer_access_scope`
65 | authorization request parameter set to a list of space-delimited scopes the `token` claim will be enabled for. If no
66 | `bearer_access_scope` parameter is present, the `token` claim SHOULD not be included.
67 |
68 |
69 | A non-normative OpenAPI spec of an [=STS=] implementing client credentials flow is provided [here](specifications/identity-trust-sts-api.yaml)
70 |
71 |
72 | ### Validating Self-Issued ID Tokens
73 |
74 | The [=Verifier=] MUST validate the Self-Issued ID Token using the following steps:
75 |
76 | 1. The [=Verifier=] MUST assert that the `iss` and `sub` claims have the same DID value.
77 | 2. The [=Verifier=] MUST assert that the `aud` claim is set to the [=Verifier=] [=DID=].
78 | 3. The [=Verifier=] MUST validate the signature of the Self-Issued ID token by using a key obtained from the resolved
79 | `sub` DID Document. [=DID=] resolution is performed according to the [=DID=] Method specified by the `sub` claim. The
80 | resolved DID document is processed to retrieve the value of the `verificationMethod` property.
81 | - The signing key MUST have `capabilityInvocation` verification relationship with the DID.
82 | - If no `kid` token header is specified and the `verificationMethod` property contains one entry and the entry has the `capabilityInvocation` verification relationship, the verification method is used.
83 | - If no `kid` token header is specified and the `verificationMethod` property contains more than one entry, the token is rejected.
84 | - If a `kid` token header is specified, the verification material from the entry corresponding the `kid` token header is
85 | used. Furthermore, this verification material MUST have `capabilityInvocation` verification relationship.
86 | - If no matching entry is found, the token is rejected.
87 | 4. The [=Verifier=] MUST assert that the `sub` claim value equals the `id` property in the DID Document.
88 | 5. The [=Verifier=] MUST assert the `nbf` claim if present. The [=Verifier=] MAY allow for some leeway to account for
89 | clock skew.
90 | 5. The [=Verifier=] MUST assert that the current time is before the time represented by the `exp` claim.
91 | The [=Verifier=] MAY allow for some leeway to account for clock skew. The `iat` claim MAY be used to reject a token
92 | that was issued much earlier than the current time, thereby limiting the amount of time a `jti` value needs to be
93 | stored.
94 | 6. The [=Verifier=] MUST assert that the `jti` claim value has not been used previously.
95 |
96 | # Schemas, Contexts, and Message Processing
97 |
98 | All protocol messages are normatively defined by a [[json-schema]]. This specification also uses [[[json-ld11]]] and
99 | provides a Json-Ld context to serialize data structures and message types as it facilitates extensibility. The Json-Ld
100 | context is designed to produce message serializations using compaction that validate against the Json Schema for the
101 | given message type. This allows implementations to choose whether to process messages as plain Json or as Json-Ld and
102 | maintain interoperability between those approaches. Extensions that use Json-Ld are encouraged to provide similar
103 | contexts that facilitate this approach to interoperability.
104 |
105 | ## The Decentralized Claims Protocol Context
106 |
107 | The [[[json-ld11]]] context URI for the specification is: `https://w3id.org/dspace-dcp/v1.0/dcp.jsonld`. Future
108 | specification releases SHALL reuse the versioning schema according to the [Semantic Versioning](https://semver.org/)
109 | definitions, concatenated to a `vMAJOR.MINOR` number. The current specifications use `1.0` version.
110 |
111 | # The Base URL
112 |
113 | All endpoint URLs in this specification are relative. The base URL MUST use the HTTPS scheme. The base URL is
114 | implementation-specific and MAY include additional context information such as a sub-path that disambiguates a holder.
115 |
--------------------------------------------------------------------------------
/specifications/participant-agent-model.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Verifier
5 | Verifies VCs
6 |
7 | Participant Agent
8 |
9 |
10 |
11 |
12 | Credential
Service
13 |
14 | STS
15 |
16 | Participant Agent
17 |
18 | DID
Service
19 | Holder
20 | Acquires and presents VCs
21 |
22 | Issue token
23 |
24 | Verify token
25 |
26 | Update DID document
27 | Use schemas
28 |
29 | Verify identifiers and use schemas
30 | Register identifiers
31 |
32 |
33 |
34 | Issuer
35 | Issues VCs
36 |
37 | Issuer Service
38 |
39 | Verify identifiers and use schemas
40 |
41 | Verifiable Data Registry
42 | Maintains identifiers and schemas
43 |
44 | Dataspace Protocol
45 |
46 | DCP Presentation
47 |
48 | DCP Issuance
49 |
50 |
--------------------------------------------------------------------------------
/specifications/trust.model.md:
--------------------------------------------------------------------------------
1 | # Trust Model and Information Flow Architecture
2 |
3 | This specification is based on the Issuer-Holder-Verifier model as described in the [VC DataModel version of the selected profile](#profiles-of-the-decentralized-claims-protocol):
4 |
5 | 
6 |
7 | In this model, the [=Issuer=] creates a [=Verifiable Credential=] and provides it to the [=Holder=], which can then
8 | present the [=Verifiable Credential=] to the [=Verifier=].
9 |
10 | The [=Verifier=] decides which [=Verifiable Credentials=] it will accept and the [=Holder=] decides
11 | which [=Verifiable Credentials=] it will present. All parties rely on a [=Verifiable Data Registry=] to obtain
12 | identifier information and metadata about [=Verifiable Credentials=], such as
13 | schemas. Furthermore, parties communicate with each other using the protocols defined in the Dataspace Protocol
14 | specification [[dsp-base]] and this specification.
15 |
16 | The Issuer-Holder-Verifier model is mapped to the following architecture in this specification:
17 |
18 | 
19 |
20 | - Identity and claims information is exchanged between a [=Holder=] and a [=Verifier=] in the context of Dataspace
21 | Protocol message interactions [[dsp-base]]. These messages will contain metadata such as Offers and Agreements that
22 | determine the [=Verifiable Credentials=] a [=Holder=] MUST present to a [=Verifier=].
23 | - The [=Issuer Service=] issues credentials to a [=Holder=]'s [=Credential Service=] using the protocol defined in
24 | Section [[[#credential-issuance-protocol]]]. As part of this process, the [=Issuer Service=] will verify
25 | the [=Holder=]'s identifier using the [=Verifiable Data Registry=]. Since [=DID=]s are mandatory in this
26 | specification, the registry will be used to resolve the [=Holder=]'s DID document and cryptographic material.
27 | - The [=Holder=] runs three logical services: a [=Participant Agent=], an [=STS=], and a [=Credential Service=].
28 | The [=Participant Agent=] engages in dataspace communications with the [=Verifier=] agent [[dsp-base]]. As part of
29 | these interactions, the [=Participant Agent=] will include a Self-Issued ID Token as defined in
30 | Section [[[#self-issued-id-tokens]]]. This token will be obtained from the [=STS=] controlled by the [=Holder=].
31 | **Note that the [=STS=] is an internal system and therefore out of scope for the current specification. It MAY be a
32 | standalone service or part of the [=Participant Agent=] or [=Credential Service=].** The Self-Issued ID Token will
33 | contain an access token bound to the [=Verifier=] that will be used to request a [=Verifiable Presentation=].
34 | The [=Holder=]'s [=Credential Service=] will verify the access token with the [=STS=].
35 | - The [=Verifier=] runs a [=Participant Agent=] that engages in dataspace message exchanges with the [=Holder=]
36 | agent [[dsp-base]]. When it receives a request, it will resolve the [=Holder=]'s DID document from
37 | the [=Verifiable Data Registry=]. The [=Participant Agent=] will resolve the [=Credential Service=] endpoint from the
38 | DID document. The [=Participant Agent=] will send a request for a [=Verifiable Presentation=] to
39 | the [=Credential Service=] using the protocol defined in Section [[[#verifiable-presentation-protocol]]]. This
40 | request will include the access token as a claim in the Self-Issued ID Token received from the [=Holder=]'s agent.
41 | The [=Participant Agent=] will then match the credentials returned in the [=Verifiable Presentation=] against the
42 | policy constraints associated with the original dataspace request.
43 |
44 | ## Consent
45 |
46 | Consent is the process where the [=Holder=] approves the release of a [=Verifiable Presentation=] and the [=Verifier=]
47 | agrees to allow access to a protected resource. Since the Dataspace Protocol is built on machine-to-machine message
48 | exchange patterns, presentation protocols that rely on end-user (i.e., human) consent are not applicable. The protocols
49 | defined in this specification establish consent in the following way:
50 |
51 | 
52 |
53 | Consent is handled by first mapping Dataspace Protocol Offer and Agreement policies [[dsp-base]] to a set of
54 | REQUIRED [=Verifiable Credentials=]. The exact mappings are dataspace-specific as policies
55 | and [=Verifiable Credentials=] are typically defined for a particular domain. The expectation is that these mappings are
56 | made available by the [=Dataspace Governance Authority=] to [=Participant Agents=] via
57 | the [=Verifiable Data Registry=]. [=Verifiable Credential=] mapping is done by both the [=Holder=]
58 | and [=Verifier=] [=Participant Agent=] when a Dataspace Protocol message is sent and received.
59 |
60 | When sending a Dataspace Protocol message, the [=Holder=]'s [=Participant Agent=] will determine the REQUIRED
61 | [=Verifiable Credentials=] and issue a Self-Issued ID Token request to the [=STS=], including the list of credentials to
62 | allow the [=Verifier=] to access via the [=Credential Service=]. The returned Self-Issued ID token will contain an
63 | access token bound to the [=Verifier=] as described above. This access token serves as a verifiable mechanism
64 | the [=Credential Service=] uses to determine consent and release credentials to the [=Verifier=].
65 |
66 | The [=Verifier=] establishes consent by performing the same mapping from metadata to a set
67 | of [=Verifiable Credentials=] during the initial Dataspace Protocol request. At that point,
68 | the [=Verifier=] [=Participant Agent=] can query the [=Credential Service=] for a [=Verifiable Presentation=]. If it
69 | matches the REQUIRED credentials, the [=Verifier=] can consent and grant access to the associated protected resources.
70 |
71 | ## Trust Relationships
72 |
73 | Trust in the Issuer-Holder-Verifier model is established in different ways between each entity. This section identifies
74 | key aspects of those trust relationships.
75 |
76 | **All Entities**
77 |
78 | All entities expect:
79 |
80 | - The [=Verifiable Data Registry=] to be tamper-evident and correctly reflect data controlled by all entities. This MAY
81 | be done through the use of cryptographic resources.
82 | - All [=Verifiable Credentials=] and [=Verifiable Presentations=] to be tamper-proof and support revocation.
83 | - Dataspace Protocol interactions and those defined in this specification to be secure and use Transport Level
84 | Security.
85 |
86 | **Issuer**
87 |
88 | The [=Issuer=] expects:
89 |
90 | - [=Credential Service=] integrity, i.e. that [=Verifiable Credentials=] are securely stored and the service does not
91 | reveal data to unauthorized parties.
92 |
93 | **Holder**
94 |
95 | The [=Holder=] expects:
96 |
97 | - The [=Dataspace Governance Authority=] to provide a secure list of trusted [=Issuer=] [=DID=]s. How this list is provided is out
98 | of scope of the current specification but MAY be part of the [=Verifiable Data Registry=].
99 | - The [=Dataspace Governance Authority=] to provide a secure list of participant [=DIDs=]. How this list is provided is out
100 | of scope of the current specification but MAY be part of the [=Verifiable Data Registry=].
101 | - The [=Credential Service=] to maintain integrity and not release data to unauthorized parties.
102 | - The [=Issuer=] to issue credentials correctly, including binding them to the holder in a tamper-proof way, and
103 | maintaining credential integrity.
104 | - The [=Verifier=] not to leak information to third-parties.
105 |
106 | **Verifier**
107 |
108 | The [=Verifier=] expects:
109 |
110 | - The [=Dataspace Governance Authority=] to provide a secure list of trusted [=Issuer=] [=DID=]s. How this list is provided is out
111 | of scope of the current specification but MAY be part of the [=Verifiable Data Registry=]. [=Verifiers=] can
112 | recognize several [=Dataspace Governance Authorities=].
113 |
114 | - The [=Issuer=] to issue credentials correctly, including binding them to the holder in a tamper-proof way, and
115 | maintaining credential integrity.
116 |
117 | ## Transport Security
118 |
119 | All participants MUST communicate via HTTPS [[rfc9110]].
120 |
--------------------------------------------------------------------------------
/specifications/auth.flow.svg:
--------------------------------------------------------------------------------
1 | Client Entity Verifier Entity Client Client Secure Token Service Secure Token Service DID Service DID Service Credential Service Credential Service Verifier Verifier 1 request 2 response incl. access token 3 request w/ self-issued id token incl. access token 4 resolve DID 5 DID document response 6 request w/ self-issued id token incl. access token 7 VP response 8 response
--------------------------------------------------------------------------------
/specifications/issuance.flow.svg:
--------------------------------------------------------------------------------
1 | Client Entity Issuer Entity Client Client Secure Token Service Secure Token Service DID Service DID Service Credential Service Credential Service Issuer Service Issuer Service 1 request 2 response incl. access token 3 request credential(s) w/ self-issued ID token incl. access token 4 resolve DID 5 DID document response 6 ack 7 (async) write credential(s) w/ self-issued ID token access token 8 Validate token and store credentials
--------------------------------------------------------------------------------
/artifacts/src/main/resources/context/odrl.jsonld:
--------------------------------------------------------------------------------
1 | {
2 | "@context": {
3 | "odrl": "http://www.w3.org/ns/odrl/2/",
4 | "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
5 | "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
6 | "owl": "http://www.w3.org/2002/07/owl#",
7 | "skos": "http://www.w3.org/2004/02/skos/core#",
8 | "dct": "http://purl.org/dc/terms/",
9 | "xsd": "http://www.w3.org/2001/XMLSchema#",
10 | "vcard": "http://www.w3.org/2006/vcard/ns#",
11 | "foaf": "http://xmlns.com/foaf/0.1/",
12 | "schema": "http://schema.org/",
13 | "cc": "http://creativecommons.org/ns#",
14 | "uid": "@id",
15 | "type": "@type",
16 | "Policy": "odrl:Policy",
17 | "Rule": "odrl:Rule",
18 | "profile": {
19 | "@type": "@id",
20 | "@id": "odrl:profile"
21 | },
22 | "inheritFrom": {
23 | "@type": "@id",
24 | "@id": "odrl:inheritFrom"
25 | },
26 | "ConflictTerm": "odrl:ConflictTerm",
27 | "conflict": {
28 | "@type": "@vocab",
29 | "@id": "odrl:conflict"
30 | },
31 | "perm": "odrl:perm",
32 | "prohibit": "odrl:prohibit",
33 | "invalid": "odrl:invalid",
34 | "Agreement": "odrl:Agreement",
35 | "Assertion": "odrl:Assertion",
36 | "Offer": "odrl:Offer",
37 | "Privacy": "odrl:Privacy",
38 | "Request": "odrl:Request",
39 | "Set": "odrl:Set",
40 | "Ticket": "odrl:Ticket",
41 | "Asset": "odrl:Asset",
42 | "AssetCollection": "odrl:AssetCollection",
43 | "relation": {
44 | "@type": "@id",
45 | "@id": "odrl:relation"
46 | },
47 | "hasPolicy": {
48 | "@type": "@id",
49 | "@id": "odrl:hasPolicy"
50 | },
51 | "target": {
52 | "@type": "@id",
53 | "@id": "odrl:target"
54 | },
55 | "output": {
56 | "@type": "@id",
57 | "@id": "odrl:output"
58 | },
59 | "partOf": {
60 | "@type": "@id",
61 | "@id": "odrl:partOf"
62 | },
63 | "source": {
64 | "@type": "@id",
65 | "@id": "odrl:source"
66 | },
67 | "Party": "odrl:Party",
68 | "PartyCollection": "odrl:PartyCollection",
69 | "function": {
70 | "@type": "@vocab",
71 | "@id": "odrl:function"
72 | },
73 | "PartyScope": "odrl:PartyScope",
74 | "assignee": {
75 | "@type": "@id",
76 | "@id": "odrl:assignee"
77 | },
78 | "assigner": {
79 | "@type": "@id",
80 | "@id": "odrl:assigner"
81 | },
82 | "assigneeOf": {
83 | "@type": "@id",
84 | "@id": "odrl:assigneeOf"
85 | },
86 | "assignerOf": {
87 | "@type": "@id",
88 | "@id": "odrl:assignerOf"
89 | },
90 | "attributedParty": {
91 | "@type": "@id",
92 | "@id": "odrl:attributedParty"
93 | },
94 | "attributingParty": {
95 | "@type": "@id",
96 | "@id": "odrl:attributingParty"
97 | },
98 | "compensatedParty": {
99 | "@type": "@id",
100 | "@id": "odrl:compensatedParty"
101 | },
102 | "compensatingParty": {
103 | "@type": "@id",
104 | "@id": "odrl:compensatingParty"
105 | },
106 | "consentingParty": {
107 | "@type": "@id",
108 | "@id": "odrl:consentingParty"
109 | },
110 | "consentedParty": {
111 | "@type": "@id",
112 | "@id": "odrl:consentedParty"
113 | },
114 | "informedParty": {
115 | "@type": "@id",
116 | "@id": "odrl:informedParty"
117 | },
118 | "informingParty": {
119 | "@type": "@id",
120 | "@id": "odrl:informingParty"
121 | },
122 | "trackingParty": {
123 | "@type": "@id",
124 | "@id": "odrl:trackingParty"
125 | },
126 | "trackedParty": {
127 | "@type": "@id",
128 | "@id": "odrl:trackedParty"
129 | },
130 | "contractingParty": {
131 | "@type": "@id",
132 | "@id": "odrl:contractingParty"
133 | },
134 | "contractedParty": {
135 | "@type": "@id",
136 | "@id": "odrl:contractedParty"
137 | },
138 | "Action": "odrl:Action",
139 | "action": {
140 | "@type": "@vocab",
141 | "@id": "odrl:action"
142 | },
143 | "includedIn": {
144 | "@type": "@id",
145 | "@id": "odrl:includedIn"
146 | },
147 | "implies": {
148 | "@type": "@id",
149 | "@id": "odrl:implies"
150 | },
151 | "Permission": "odrl:Permission",
152 | "permission": {
153 | "@type": "@id",
154 | "@id": "odrl:permission"
155 | },
156 | "Prohibition": "odrl:Prohibition",
157 | "prohibition": {
158 | "@type": "@id",
159 | "@id": "odrl:prohibition"
160 | },
161 | "obligation": {
162 | "@type": "@id",
163 | "@id": "odrl:obligation"
164 | },
165 | "use": "odrl:use",
166 | "grantUse": "odrl:grantUse",
167 | "aggregate": "odrl:aggregate",
168 | "annotate": "odrl:annotate",
169 | "anonymize": "odrl:anonymize",
170 | "archive": "odrl:archive",
171 | "concurrentUse": "odrl:concurrentUse",
172 | "derive": "odrl:derive",
173 | "digitize": "odrl:digitize",
174 | "display": "odrl:display",
175 | "distribute": "odrl:distribute",
176 | "execute": "odrl:execute",
177 | "extract": "odrl:extract",
178 | "give": "odrl:give",
179 | "index": "odrl:index",
180 | "install": "odrl:install",
181 | "modify": "odrl:modify",
182 | "move": "odrl:move",
183 | "play": "odrl:play",
184 | "present": "odrl:present",
185 | "print": "odrl:print",
186 | "read": "odrl:read",
187 | "reproduce": "odrl:reproduce",
188 | "sell": "odrl:sell",
189 | "stream": "odrl:stream",
190 | "textToSpeech": "odrl:textToSpeech",
191 | "transfer": "odrl:transfer",
192 | "transform": "odrl:transform",
193 | "translate": "odrl:translate",
194 | "Duty": "odrl:Duty",
195 | "duty": {
196 | "@type": "@id",
197 | "@id": "odrl:duty"
198 | },
199 | "consequence": {
200 | "@type": "@id",
201 | "@id": "odrl:consequence"
202 | },
203 | "remedy": {
204 | "@type": "@id",
205 | "@id": "odrl:remedy"
206 | },
207 | "acceptTracking": "odrl:acceptTracking",
208 | "attribute": "odrl:attribute",
209 | "compensate": "odrl:compensate",
210 | "delete": "odrl:delete",
211 | "ensureExclusivity": "odrl:ensureExclusivity",
212 | "include": "odrl:include",
213 | "inform": "odrl:inform",
214 | "nextPolicy": "odrl:nextPolicy",
215 | "obtainConsent": "odrl:obtainConsent",
216 | "reviewPolicy": "odrl:reviewPolicy",
217 | "uninstall": "odrl:uninstall",
218 | "watermark": "odrl:watermark",
219 | "Constraint": "odrl:Constraint",
220 | "LogicalConstraint": "odrl:LogicalConstraint",
221 | "constraint": {
222 | "@type": "@id",
223 | "@id": "odrl:constraint"
224 | },
225 | "refinement": {
226 | "@type": "@id",
227 | "@id": "odrl:refinement"
228 | },
229 | "Operator": "odrl:Operator",
230 | "operator": {
231 | "@type": "@vocab",
232 | "@id": "odrl:operator"
233 | },
234 | "RightOperand": "odrl:RightOperand",
235 | "rightOperand": "odrl:rightOperand",
236 | "rightOperandReference": {
237 | "@type": "xsd:anyURI",
238 | "@id": "odrl:rightOperandReference"
239 | },
240 | "LeftOperand": "odrl:LeftOperand",
241 | "leftOperand": {
242 | "@type": "@vocab",
243 | "@id": "odrl:leftOperand"
244 | },
245 | "unit": "odrl:unit",
246 | "dataType": {
247 | "@type": "xsd:anyType",
248 | "@id": "odrl:datatype"
249 | },
250 | "status": "odrl:status",
251 | "absolutePosition": "odrl:absolutePosition",
252 | "absoluteSpatialPosition": "odrl:absoluteSpatialPosition",
253 | "absoluteTemporalPosition": "odrl:absoluteTemporalPosition",
254 | "absoluteSize": "odrl:absoluteSize",
255 | "count": "odrl:count",
256 | "dateTime": "odrl:dateTime",
257 | "delayPeriod": "odrl:delayPeriod",
258 | "deliveryChannel": "odrl:deliveryChannel",
259 | "elapsedTime": "odrl:elapsedTime",
260 | "event": "odrl:event",
261 | "fileFormat": "odrl:fileFormat",
262 | "industry": "odrl:industry:",
263 | "language": "odrl:language",
264 | "media": "odrl:media",
265 | "meteredTime": "odrl:meteredTime",
266 | "payAmount": "odrl:payAmount",
267 | "percentage": "odrl:percentage",
268 | "product": "odrl:product",
269 | "purpose": "odrl:purpose",
270 | "recipient": "odrl:recipient",
271 | "relativePosition": "odrl:relativePosition",
272 | "relativeSpatialPosition": "odrl:relativeSpatialPosition",
273 | "relativeTemporalPosition": "odrl:relativeTemporalPosition",
274 | "relativeSize": "odrl:relativeSize",
275 | "resolution": "odrl:resolution",
276 | "spatial": "odrl:spatial",
277 | "spatialCoordinates": "odrl:spatialCoordinates",
278 | "systemDevice": "odrl:systemDevice",
279 | "timeInterval": "odrl:timeInterval",
280 | "unitOfCount": "odrl:unitOfCount",
281 | "version": "odrl:version",
282 | "virtualLocation": "odrl:virtualLocation",
283 | "eq": "odrl:eq",
284 | "gt": "odrl:gt",
285 | "gteq": "odrl:gteq",
286 | "lt": "odrl:lt",
287 | "lteq": "odrl:lteq",
288 | "neq": "odrl:neg",
289 | "isA": "odrl:isA",
290 | "hasPart": "odrl:hasPart",
291 | "isPartOf": "odrl:isPartOf",
292 | "isAllOf": "odrl:isAllOf",
293 | "isAnyOf": "odrl:isAnyOf",
294 | "isNoneOf": "odrl:isNoneOf",
295 | "or": "odrl:or",
296 | "xone": "odrl:xone",
297 | "and": "odrl:and",
298 | "andSequence": "odrl:andSequence",
299 | "policyUsage": "odrl:policyUsage"
300 | }
301 | }
302 |
--------------------------------------------------------------------------------
/artifacts/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
88 |
89 | # Use the maximum available, or set MAX_FD != -1 to use that value.
90 | MAX_FD=maximum
91 |
92 | warn () {
93 | echo "$*"
94 | } >&2
95 |
96 | die () {
97 | echo
98 | echo "$*"
99 | echo
100 | exit 1
101 | } >&2
102 |
103 | # OS specific support (must be 'true' or 'false').
104 | cygwin=false
105 | msys=false
106 | darwin=false
107 | nonstop=false
108 | case "$( uname )" in #(
109 | CYGWIN* ) cygwin=true ;; #(
110 | Darwin* ) darwin=true ;; #(
111 | MSYS* | MINGW* ) msys=true ;; #(
112 | NONSTOP* ) nonstop=true ;;
113 | esac
114 |
115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
116 |
117 |
118 | # Determine the Java command to use to start the JVM.
119 | if [ -n "$JAVA_HOME" ] ; then
120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
121 | # IBM's JDK on AIX uses strange locations for the executables
122 | JAVACMD=$JAVA_HOME/jre/sh/java
123 | else
124 | JAVACMD=$JAVA_HOME/bin/java
125 | fi
126 | if [ ! -x "$JAVACMD" ] ; then
127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
128 |
129 | Please set the JAVA_HOME variable in your environment to match the
130 | location of your Java installation."
131 | fi
132 | else
133 | JAVACMD=java
134 | if ! command -v java >/dev/null 2>&1
135 | then
136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
137 |
138 | Please set the JAVA_HOME variable in your environment to match the
139 | location of your Java installation."
140 | fi
141 | fi
142 |
143 | # Increase the maximum file descriptors if we can.
144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
145 | case $MAX_FD in #(
146 | max*)
147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
148 | # shellcheck disable=SC2039,SC3045
149 | MAX_FD=$( ulimit -H -n ) ||
150 | warn "Could not query maximum file descriptor limit"
151 | esac
152 | case $MAX_FD in #(
153 | '' | soft) :;; #(
154 | *)
155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
156 | # shellcheck disable=SC2039,SC3045
157 | ulimit -n "$MAX_FD" ||
158 | warn "Could not set maximum file descriptor limit to $MAX_FD"
159 | esac
160 | fi
161 |
162 | # Collect all arguments for the java command, stacking in reverse order:
163 | # * args from the command line
164 | # * the main class name
165 | # * -classpath
166 | # * -D...appname settings
167 | # * --module-path (only if needed)
168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
169 |
170 | # For Cygwin or MSYS, switch paths to Windows format before running java
171 | if "$cygwin" || "$msys" ; then
172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
174 |
175 | JAVACMD=$( cygpath --unix "$JAVACMD" )
176 |
177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
178 | for arg do
179 | if
180 | case $arg in #(
181 | -*) false ;; # don't mess with options #(
182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
183 | [ -e "$t" ] ;; #(
184 | *) false ;;
185 | esac
186 | then
187 | arg=$( cygpath --path --ignore --mixed "$arg" )
188 | fi
189 | # Roll the args list around exactly as many times as the number of
190 | # args, so each arg winds up back in the position where it started, but
191 | # possibly modified.
192 | #
193 | # NB: a `for` loop captures its iteration list before it begins, so
194 | # changing the positional parameters here affects neither the number of
195 | # iterations, nor the values presented in `arg`.
196 | shift # remove old arg
197 | set -- "$@" "$arg" # push replacement arg
198 | done
199 | fi
200 |
201 |
202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
204 |
205 | # Collect all arguments for the java command:
206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
207 | # and any embedded shellness will be escaped.
208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
209 | # treated as '${Hostname}' itself on the command line.
210 |
211 | set -- \
212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
213 | -classpath "$CLASSPATH" \
214 | org.gradle.wrapper.GradleWrapperMain \
215 | "$@"
216 |
217 | # Stop when "xargs" is not available.
218 | if ! command -v xargs >/dev/null 2>&1
219 | then
220 | die "xargs is not available"
221 | fi
222 |
223 | # Use "xargs" to parse quoted args.
224 | #
225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
226 | #
227 | # In Bash we could simply go:
228 | #
229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
230 | # set -- "${ARGS[@]}" "$@"
231 | #
232 | # but POSIX shell has neither arrays nor command substitution, so instead we
233 | # post-process each arg (as a line of input to sed) to backslash-escape any
234 | # character that might be a shell metacharacter, then use eval to reverse
235 | # that process (while maintaining the separation between arguments), and wrap
236 | # the whole thing up as a single "set" statement.
237 | #
238 | # This will of course break if any of these variables contains a newline or
239 | # an unmatched quote.
240 | #
241 |
242 | eval "set -- $(
243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
244 | xargs -n1 |
245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
246 | tr '\n' ' '
247 | )" '"$@"'
248 |
249 | exec "$JAVACMD" "$@"
250 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/artifacts/src/test/resources/presentation-exchange/schemas/presentation-definition.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "$schema": "http://json-schema.org/draft-07/schema#",
4 | "title": "Presentation Definition",
5 | "definitions": {
6 | "status_directive": {
7 | "type": "object",
8 | "additionalProperties": false,
9 | "properties": {
10 | "directive": {
11 | "type": "string",
12 | "enum": [
13 | "required",
14 | "allowed",
15 | "disallowed"
16 | ]
17 | },
18 | "type": {
19 | "type": "array",
20 | "minItems": 1,
21 | "items": {
22 | "type": "string"
23 | }
24 | }
25 | }
26 | },
27 | "field": {
28 | "type": "object",
29 | "oneOf": [
30 | {
31 | "properties": {
32 | "id": {
33 | "type": "string"
34 | },
35 | "optional": {
36 | "type": "boolean"
37 | },
38 | "path": {
39 | "type": "array",
40 | "items": {
41 | "type": "string"
42 | }
43 | },
44 | "purpose": {
45 | "type": "string"
46 | },
47 | "name": {
48 | "type": "string"
49 | },
50 | "intent_to_retain": {
51 | "type": "boolean"
52 | },
53 | "filter": {
54 | "$ref": "http://json-schema.org/draft-07/schema#"
55 | }
56 | },
57 | "required": [
58 | "path"
59 | ],
60 | "additionalProperties": false
61 | },
62 | {
63 | "properties": {
64 | "id": {
65 | "type": "string"
66 | },
67 | "optional": {
68 | "type": "boolean"
69 | },
70 | "path": {
71 | "type": "array",
72 | "items": {
73 | "type": "string"
74 | }
75 | },
76 | "purpose": {
77 | "type": "string"
78 | },
79 | "intent_to_retain": {
80 | "type": "boolean"
81 | },
82 | "filter": {
83 | "$ref": "http://json-schema.org/draft-07/schema#"
84 | },
85 | "name": {
86 | "type": "string"
87 | },
88 | "predicate": {
89 | "type": "string",
90 | "enum": [
91 | "required",
92 | "preferred"
93 | ]
94 | }
95 | },
96 | "required": [
97 | "path",
98 | "filter",
99 | "predicate"
100 | ],
101 | "additionalProperties": false
102 | }
103 | ]
104 | },
105 | "input_descriptor": {
106 | "type": "object",
107 | "additionalProperties": false,
108 | "properties": {
109 | "id": {
110 | "type": "string"
111 | },
112 | "name": {
113 | "type": "string"
114 | },
115 | "purpose": {
116 | "type": "string"
117 | },
118 | "format": {
119 | "$ref": "https://identity.foundation/claim-format-registry/schemas/presentation-definition-claim-format-designations.json"
120 | },
121 | "group": {
122 | "type": "array",
123 | "items": {
124 | "type": "string"
125 | }
126 | },
127 | "constraints": {
128 | "type": "object",
129 | "additionalProperties": false,
130 | "properties": {
131 | "limit_disclosure": {
132 | "type": "string",
133 | "enum": [
134 | "required",
135 | "preferred"
136 | ]
137 | },
138 | "statuses": {
139 | "type": "object",
140 | "additionalProperties": false,
141 | "properties": {
142 | "active": {
143 | "$ref": "#/definitions/status_directive"
144 | },
145 | "suspended": {
146 | "$ref": "#/definitions/status_directive"
147 | },
148 | "revoked": {
149 | "$ref": "#/definitions/status_directive"
150 | }
151 | }
152 | },
153 | "fields": {
154 | "type": "array",
155 | "items": {
156 | "$ref": "#/definitions/field"
157 | }
158 | },
159 | "subject_is_issuer": {
160 | "type": "string",
161 | "enum": [
162 | "required",
163 | "preferred"
164 | ]
165 | },
166 | "is_holder": {
167 | "type": "array",
168 | "items": {
169 | "type": "object",
170 | "additionalProperties": false,
171 | "properties": {
172 | "field_id": {
173 | "type": "array",
174 | "items": {
175 | "type": "string"
176 | }
177 | },
178 | "directive": {
179 | "type": "string",
180 | "enum": [
181 | "required",
182 | "preferred"
183 | ]
184 | }
185 | },
186 | "required": [
187 | "field_id",
188 | "directive"
189 | ]
190 | }
191 | },
192 | "same_subject": {
193 | "type": "array",
194 | "items": {
195 | "type": "object",
196 | "additionalProperties": false,
197 | "properties": {
198 | "field_id": {
199 | "type": "array",
200 | "items": {
201 | "type": "string"
202 | }
203 | },
204 | "directive": {
205 | "type": "string",
206 | "enum": [
207 | "required",
208 | "preferred"
209 | ]
210 | }
211 | },
212 | "required": [
213 | "field_id",
214 | "directive"
215 | ]
216 | }
217 | }
218 | }
219 | }
220 | },
221 | "required": [
222 | "id",
223 | "constraints"
224 | ]
225 | },
226 | "submission_requirement": {
227 | "type": "object",
228 | "oneOf": [
229 | {
230 | "properties": {
231 | "name": {
232 | "type": "string"
233 | },
234 | "purpose": {
235 | "type": "string"
236 | },
237 | "rule": {
238 | "type": "string",
239 | "enum": [
240 | "all",
241 | "pick"
242 | ]
243 | },
244 | "count": {
245 | "type": "integer",
246 | "minimum": 1
247 | },
248 | "min": {
249 | "type": "integer",
250 | "minimum": 0
251 | },
252 | "max": {
253 | "type": "integer",
254 | "minimum": 0
255 | },
256 | "from": {
257 | "type": "string"
258 | }
259 | },
260 | "required": [
261 | "rule",
262 | "from"
263 | ],
264 | "additionalProperties": false
265 | },
266 | {
267 | "properties": {
268 | "name": {
269 | "type": "string"
270 | },
271 | "purpose": {
272 | "type": "string"
273 | },
274 | "rule": {
275 | "type": "string",
276 | "enum": [
277 | "all",
278 | "pick"
279 | ]
280 | },
281 | "count": {
282 | "type": "integer",
283 | "minimum": 1
284 | },
285 | "min": {
286 | "type": "integer",
287 | "minimum": 0
288 | },
289 | "max": {
290 | "type": "integer",
291 | "minimum": 0
292 | },
293 | "from_nested": {
294 | "type": "array",
295 | "minItems": 1,
296 | "items": {
297 | "$ref": "#/definitions/submission_requirement"
298 | }
299 | }
300 | },
301 | "required": [
302 | "rule",
303 | "from_nested"
304 | ],
305 | "additionalProperties": false
306 | }
307 | ]
308 | }
309 | },
310 | "type": "object",
311 | "properties": {
312 | "id": {
313 | "type": "string"
314 | },
315 | "name": {
316 | "type": "string"
317 | },
318 | "purpose": {
319 | "type": "string"
320 | },
321 | "format": {
322 | "$ref": "https://identity.foundation/claim-format-registry/schemas/presentation-definition-claim-format-designations.json"
323 | },
324 | "frame": {
325 | "type": "object",
326 | "additionalProperties": true
327 | },
328 | "submission_requirements": {
329 | "type": "array",
330 | "items": {
331 | "$ref": "#/definitions/submission_requirement"
332 | }
333 | },
334 | "input_descriptors": {
335 | "type": "array",
336 | "items": {
337 | "$ref": "#/definitions/input_descriptor"
338 | }
339 | }
340 | },
341 | "required": [
342 | "id",
343 | "input_descriptors"
344 | ],
345 | "additionalProperties": false
346 | }
347 |
--------------------------------------------------------------------------------