From 88779dea6b851b2b9bba552b94cdeda2926b61db Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Wed, 6 Dec 2023 14:07:47 +0100 Subject: [PATCH 1/4] feat: add DID module --- .../identity-hub-credentials/build.gradle.kts | 1 - core/identity-hub-did/build.gradle.kts | 12 ++ .../identityhub/did/DidResourceManager.java | 18 +++ .../identityhub/did/DidServicesExtension.java | 18 +++ ...rg.eclipse.edc.spi.system.ServiceExtension | 15 ++ .../src/main/resources/did.json | 57 ++++++++ .../src/test/resources/did.json | 57 ++++++++ settings.gradle.kts | 2 + spi/identity-hub-did-spi/build.gradle.kts | 27 ++++ .../did/spi/DidDocumentPublisher.java | 50 +++++++ .../did/spi/DidDocumentService.java | 41 ++++++ .../identithub/did/spi/model/DidResource.java | 128 ++++++++++++++++++ .../identithub/did/spi/model/DidState.java | 48 +++++++ .../did/spi/store/DidResourceStore.java | 70 ++++++++++ 14 files changed, 543 insertions(+), 1 deletion(-) create mode 100644 core/identity-hub-did/build.gradle.kts create mode 100644 core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidResourceManager.java create mode 100644 core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java create mode 100644 core/identity-hub-did/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension create mode 100644 core/identity-hub-did/src/main/resources/did.json create mode 100644 core/identity-hub-did/src/test/resources/did.json create mode 100644 spi/identity-hub-did-spi/build.gradle.kts create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentService.java create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidState.java create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java diff --git a/core/identity-hub-credentials/build.gradle.kts b/core/identity-hub-credentials/build.gradle.kts index 819db3b41..48190ef62 100644 --- a/core/identity-hub-credentials/build.gradle.kts +++ b/core/identity-hub-credentials/build.gradle.kts @@ -7,7 +7,6 @@ dependencies { api(project(":spi:identity-hub-store-spi")) implementation(libs.edc.core.connector) // for the CriterionToPredicateConverterImpl implementation(libs.edc.spi.jsonld) - implementation(libs.edc.spi.jsonld) implementation(libs.edc.ext.jsonld) // for the JSON-LD mapper implementation(libs.edc.iatp.service) // JWT validator implementation(libs.edc.core.crypto) // JWT verifier diff --git a/core/identity-hub-did/build.gradle.kts b/core/identity-hub-did/build.gradle.kts new file mode 100644 index 000000000..4d4943e90 --- /dev/null +++ b/core/identity-hub-did/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + `java-library` +} + +dependencies { + api(project(":spi:identity-hub-spi")) + + testImplementation(libs.edc.junit) + testImplementation(libs.edc.ext.jsonld) + testImplementation(testFixtures(project(":spi:identity-hub-spi"))) + testImplementation(libs.edc.identity.did.crypto) // EC private key wrapper +} diff --git a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidResourceManager.java b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidResourceManager.java new file mode 100644 index 000000000..e248190ed --- /dev/null +++ b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidResourceManager.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identityhub.did; + +public class DidResourceManager { +} diff --git a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java new file mode 100644 index 000000000..89787baa5 --- /dev/null +++ b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identityhub.did; + +public class DidServicesExtension { +} diff --git a/core/identity-hub-did/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/core/identity-hub-did/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension new file mode 100644 index 000000000..308271903 --- /dev/null +++ b/core/identity-hub-did/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation +# +# + +org.eclipse.edc.identityhub.did.DidServicesExtension \ No newline at end of file diff --git a/core/identity-hub-did/src/main/resources/did.json b/core/identity-hub-did/src/main/resources/did.json new file mode 100644 index 000000000..511d12ef5 --- /dev/null +++ b/core/identity-hub-did/src/main/resources/did.json @@ -0,0 +1,57 @@ +{ + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "alsoKnownAs": { + "@id": "https://www.w3.org/ns/activitystreams#alsoKnownAs", + "@type": "@id" + }, + "assertionMethod": { + "@id": "https://w3id.org/security#assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "https://w3id.org/security#authenticationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityDelegation": { + "@id": "https://w3id.org/security#capabilityDelegationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityInvocation": { + "@id": "https://w3id.org/security#capabilityInvocationMethod", + "@type": "@id", + "@container": "@set" + }, + "controller": { + "@id": "https://w3id.org/security#controller", + "@type": "@id" + }, + "keyAgreement": { + "@id": "https://w3id.org/security#keyAgreementMethod", + "@type": "@id", + "@container": "@set" + }, + "service": { + "@id": "https://www.w3.org/ns/did#service", + "@type": "@id", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "serviceEndpoint": { + "@id": "https://www.w3.org/ns/did#serviceEndpoint", + "@type": "@id" + } + } + }, + "verificationMethod": { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id" + } + } +} \ No newline at end of file diff --git a/core/identity-hub-did/src/test/resources/did.json b/core/identity-hub-did/src/test/resources/did.json new file mode 100644 index 000000000..511d12ef5 --- /dev/null +++ b/core/identity-hub-did/src/test/resources/did.json @@ -0,0 +1,57 @@ +{ + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "alsoKnownAs": { + "@id": "https://www.w3.org/ns/activitystreams#alsoKnownAs", + "@type": "@id" + }, + "assertionMethod": { + "@id": "https://w3id.org/security#assertionMethod", + "@type": "@id", + "@container": "@set" + }, + "authentication": { + "@id": "https://w3id.org/security#authenticationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityDelegation": { + "@id": "https://w3id.org/security#capabilityDelegationMethod", + "@type": "@id", + "@container": "@set" + }, + "capabilityInvocation": { + "@id": "https://w3id.org/security#capabilityInvocationMethod", + "@type": "@id", + "@container": "@set" + }, + "controller": { + "@id": "https://w3id.org/security#controller", + "@type": "@id" + }, + "keyAgreement": { + "@id": "https://w3id.org/security#keyAgreementMethod", + "@type": "@id", + "@container": "@set" + }, + "service": { + "@id": "https://www.w3.org/ns/did#service", + "@type": "@id", + "@context": { + "@protected": true, + "id": "@id", + "type": "@type", + "serviceEndpoint": { + "@id": "https://www.w3.org/ns/did#serviceEndpoint", + "@type": "@id" + } + } + }, + "verificationMethod": { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id" + } + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index d2379206a..2f9eddaef 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -25,10 +25,12 @@ dependencyResolutionManagement { // SPI modules include(":spi:identity-hub-spi") include(":spi:identity-hub-store-spi") +include(":spi:identity-hub-did-spi") // core modules include(":core:identity-hub-api") include(":core:identity-hub-credentials") +include(":core:identity-hub-did") // extension modules include(":extensions:cryptography:public-key-provider") diff --git a/spi/identity-hub-did-spi/build.gradle.kts b/spi/identity-hub-did-spi/build.gradle.kts new file mode 100644 index 000000000..133467508 --- /dev/null +++ b/spi/identity-hub-did-spi/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +plugins { + `java-library` + `java-test-fixtures` + `maven-publish` +} + +val swagger: String by project + +dependencies { + + api(libs.edc.spi.identitytrust) + implementation(libs.edc.spi.identity.did) +} diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java new file mode 100644 index 000000000..881ba20c7 --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identithub.did.spi; + +import org.eclipse.edc.iam.did.spi.document.DidDocument; +import org.eclipse.edc.spi.result.Result; + +/** + * The DidDocumentPublisher is responsible for taking a {@link DidDocument} and making it available at a VDR (verifiable data registry). + * For example, an implementation may choose to publish the DID to a CDN. + */ +public interface DidDocumentPublisher { + + /** + * Checks if the given ID can be handled by the DidDocumentPublisher. IDs must contain the DID method + * (see W3C DID 1.0) + * + * @param id the ID to be checked. This must conform to the DID syntax + * @return true if the publisher can handle the ID, false otherwise + */ + boolean canHandle(String id); + + /** + * Publishes a given {@link DidDocument} to a verifiable data registry (VDR). + * + * @param document the {@link DidDocument} to be published + * @return a {@link Result} object indicating the success or failure of the operation. + */ + Result publish(DidDocument document); + + /** + * Unpublishes a given {@link DidDocument} from a verifiable data registry (VDR). + * + * @param document the {@link DidDocument} to be unpublished + * @return a {@link Result} object indicating the success or failure of the operation. + */ + Result unpublish(DidDocument document); +} diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentService.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentService.java new file mode 100644 index 000000000..f988e5e11 --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentService.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identithub.did.spi; + +import org.eclipse.edc.iam.did.spi.document.DidDocument; +import org.eclipse.edc.identithub.did.spi.model.DidState; +import org.eclipse.edc.spi.result.ServiceResult; + +/** + * The {@code DidDocumentService} gives access to a {@link DidDocument} that are held in storage. + */ +public interface DidDocumentService { + + /** + * Retrieves the {@link DidDocument} associated with the given DID, if it exists. + * + * @param did The DID for which to retrieve the DidDocument. + * @return A {@link ServiceResult} containing the DidDocument if it exists, or an error if it does not exist or cannot be retrieved. + */ + ServiceResult getDidDocument(String did); + + /** + * Retrieves the state of a DID resource. + * + * @param did The identifier of the DID resource. + * @return A {@link ServiceResult} containing the state of the DID resource if it exists. + */ + ServiceResult getState(String did); +} diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java new file mode 100644 index 000000000..2705f66b2 --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identithub.did.spi.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.eclipse.edc.iam.did.spi.document.Service; +import org.eclipse.edc.iam.did.spi.document.VerificationMethod; + +import java.time.Clock; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * This class represents a {@link org.eclipse.edc.iam.did.spi.document.DidDocument} + */ +public class DidResource { + @JsonIgnore + private Clock clock = Clock.systemUTC(); + private String did; + private DidState state = DidState.INITIAL; + private long stateTimestamp; + private long createTimestamp; + private List serviceEndpoints = new ArrayList<>(); + private List verificationMethods = new ArrayList<>(); + // todo: what is this? + // private List verificationRelationships; + + private DidResource() { + } + + public String getDid() { + return did; + } + + public DidState getState() { + return state; + } + + public long getStateTimestamp() { + return stateTimestamp; + } + + public List getServiceEndpoints() { + return serviceEndpoints; + } + + public List getVerificationMethods() { + return verificationMethods; + } + + public static final class Builder { + private final DidResource resource; + + private Builder() { + resource = new DidResource(); + } + + public Builder did(String did) { + this.resource.did = did; + return this; + } + + public Builder state(DidState state) { + this.resource.state = state; + return this; + } + + public Builder timestamp(long timestamp) { + this.resource.stateTimestamp = timestamp; + return this; + } + + public Builder clock(Clock clock) { + this.resource.clock = clock; + return this; + } + + public Builder serviceEndpoints(List serviceEndpoints) { + this.resource.serviceEndpoints = serviceEndpoints; + return this; + } + + public Builder serviceEndpoint(Service service) { + this.resource.serviceEndpoints.add(service); + return this; + } + + public Builder verificationMethods(List verificationMethodResources) { + this.resource.verificationMethods = verificationMethodResources; + return this; + } + + public Builder verificationMethod(VerificationMethod method) { + this.resource.verificationMethods.add(method); + return this; + } + + public DidResource build() { + Objects.requireNonNull(resource.did, "Must have an identifier"); + Objects.requireNonNull(resource.state, "Must have a state"); + + if (resource.stateTimestamp <= 0) { + resource.stateTimestamp = resource.clock.millis(); + } + + return resource; + } + + public static Builder newInstance() { + return new Builder(); + } + + + } +} diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidState.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidState.java new file mode 100644 index 000000000..a15e16cab --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidState.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identithub.did.spi.model; + +/** + * The DidState enum represents the state of a DID resource in the internal store. + */ +public enum DidState { + /** + * The {@link DidResource} was created in memory, but not yet persisted. This is the default state. + */ + INITIAL(100), + /** + * The {@link DidResource} was created locally in the database, but not yet published. + */ + GENERATED(200), + /** + * The {@link DidResource} has been published to a VDR. + */ + PUBLISHED(300), + /** + * The {@link DidResource} is deleted from the VDR, it is not resolvable anymore. + */ + UNPUBLISHED(400); + + private final int code; + + DidState(int code) { + + this.code = code; + } + + public int code() { + return code; + } +} diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java new file mode 100644 index 000000000..a5231c16e --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + +package org.eclipse.edc.identithub.did.spi.store; + +import org.eclipse.edc.identithub.did.spi.model.DidResource; +import org.eclipse.edc.spi.result.StoreResult; + +import java.util.List; + +/** + * The DidResourceStore interface provides CRUD methods for interacting with a store of {@link DidResource} objects. + */ +public interface DidResourceStore { + + /** + * Saves a {@link DidResource} object to the store. If a {@link DidResource} with the same {@link DidResource#getDid()} exists, + * a failure will be returned. + * + * @param resource The {@link DidResource} object to be saved. + * @return A {@link StoreResult} object indicating the success or failure of the operation. + */ + StoreResult save(DidResource resource); + + /** + * Updates a {@link DidResource} object in the store if it exists. If the {@link DidResource} does not exist, a + * failure is returned and no further database interaction takes place. + * + * @param resource The {@link DidResource} object to be updated. Note that this updates the entire object, differential + * updates are not supported. + * @return A {@link StoreResult} object indicating the success or failure of the operation. + */ + StoreResult update(DidResource resource); + + /** + * Retrieves a {@link DidResource} object from the store for the provided DID. + * + * @param did The DID to search for. + * @return The {@link DidResource} object found in the store, or null if no matching object is found. + */ + DidResource getById(String did); + + /** + * Retrieves all {@link DidResource} objects from the store. + * + * @return A {@link List} containing {@link DidResource} objects retrieved from the store. + */ + List getAll(); + + /** + * Deletes a {@link DidResource} object from the store with the specified DID. If the specified DID document does not + * exist, a failure is returned + * + * @param did The ID of the {@link DidResource} object to be deleted. + * @return A {@link StoreResult} object indicating the success or failure of the deletion operation. + */ + StoreResult deleteById(String did); + +} From ba355993e88db64d1c9ed78cc49af249e6310f24 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Thu, 7 Dec 2023 07:03:07 +0100 Subject: [PATCH 2/4] updated architecture doc --- .../identity.hub.architecture.md | 40 +++++++------------ .../identithub/did/spi/model/DidResource.java | 38 ++++++------------ 2 files changed, 27 insertions(+), 51 deletions(-) diff --git a/docs/developer/architecture/identity-trust-protocol/identity.hub.architecture.md b/docs/developer/architecture/identity-trust-protocol/identity.hub.architecture.md index 8313305c6..6741b8368 100644 --- a/docs/developer/architecture/identity-trust-protocol/identity.hub.architecture.md +++ b/docs/developer/architecture/identity-trust-protocol/identity.hub.architecture.md @@ -166,23 +166,16 @@ Services may register to receive `KeyPairManager` events, for example, when a ro ### 2.2.4. DID Resources -A `DIDResource` is a `DID` and associated entries in a `DID` document. +A `DIDResource` is a `DID` and associated entries in a `DID` document. It represents the lifecycle of a DID Document in +the IdentityHub. ```java class DidResource { String did; DidState state; - long timestamp; - List serviceEndpoints; - List verificationMethods; - List verificationRelationships; -} - -class VerificationMethod { - String id; - String type; - String material; - String keyPairResourceId; + long stateTimestamp; + long createTimestamp; + DidDocument document; } class VerificationRelationship { @@ -191,12 +184,8 @@ class VerificationRelationship { } ``` -The `serviceEndpoints` property contains a collection of `ServiceEndpoints` that can be added through configuration or -an API invocation. - -The `verificationMethods` property contains a collection of `VerificationMethods` associated with Key - -The `verificationRelationships` property contains a collection of `VerificationRelationships` associated with Key +The `DidDocument` is defined in the connector repository and is a representation of +a [W3C DID](https://www.w3.org/TR/did-core/). > NB: There is no DID manager. @@ -421,17 +410,16 @@ particular participant context. The DID module makes use of the EDC `Identity DI ### 3.6.1. DidDocumentPublisher -The `DidDocumentPublisher` is responsible for generating, provisioning and deprovisioning DID documents to -a `Verifiable Data Registry` (VDR) such as a CDN that serves a Web domain. The publisher is a state machine that can -asynchronously transition as follows: +The `DidDocumentPublisher` is responsible for generating, publishing and unpublishing DID documents to +a `Verifiable Data Registry` (VDR) such as a CDN that serves a Web domain. The publisher can transition as follows: -- **Publish**: GENERATED -> PROVISIONING -> PROVISIONED -- **Unpublish**: PROVISIONED -> DEPROVISIONING -> DEPROVISIONED -- **Republish**: PROVISIONED -> GENERATED -> PROVISIONING -> PROVISIONED +- **Publish**: GENERATED -> PUBLISHED +- **Unpublish**: PUBLISHED -> UNPUBLISHED All operations publish events. -The `DidDocumentPublisher` delegates to extensions for handling provisioning to VDRs. +There can be only one publisher per DID method, and all available publishers are kept in a `DidPublisherRegistry`, which +can be used to contribute publishers via the extension mechanism. ### 3.6.2. DidDocumentService @@ -439,6 +427,8 @@ The `DidDocumentService` returns a **managed** DID document to the requesting cl resolve foreign DID documents. Note also this service is intended for internal use. DID resolution should be performed through specific DID methods that work directly with a VDR. +The `DidDocumentService` uses the `DidResourceStore` internally. + ## 3.7. Auth/Permission Module The `Auth/Permission` module includes services that delegate to the EDC `PolicyEngine` for access control. diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java index 2705f66b2..80d66e6c8 100644 --- a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/model/DidResource.java @@ -15,16 +15,13 @@ package org.eclipse.edc.identithub.did.spi.model; import com.fasterxml.jackson.annotation.JsonIgnore; -import org.eclipse.edc.iam.did.spi.document.Service; -import org.eclipse.edc.iam.did.spi.document.VerificationMethod; +import org.eclipse.edc.iam.did.spi.document.DidDocument; import java.time.Clock; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; /** - * This class represents a {@link org.eclipse.edc.iam.did.spi.document.DidDocument} + * This class wraps a {@link org.eclipse.edc.iam.did.spi.document.DidDocument} and represents its lifecycle in the identity hub. */ public class DidResource { @JsonIgnore @@ -33,8 +30,7 @@ public class DidResource { private DidState state = DidState.INITIAL; private long stateTimestamp; private long createTimestamp; - private List serviceEndpoints = new ArrayList<>(); - private List verificationMethods = new ArrayList<>(); + private DidDocument document; // todo: what is this? // private List verificationRelationships; @@ -53,12 +49,12 @@ public long getStateTimestamp() { return stateTimestamp; } - public List getServiceEndpoints() { - return serviceEndpoints; + public long getCreateTimestamp() { + return createTimestamp; } - public List getVerificationMethods() { - return verificationMethods; + public DidDocument getDocument() { + return document; } public static final class Builder { @@ -78,7 +74,7 @@ public Builder state(DidState state) { return this; } - public Builder timestamp(long timestamp) { + public Builder stateTimeStamp(long timestamp) { this.resource.stateTimestamp = timestamp; return this; } @@ -88,23 +84,13 @@ public Builder clock(Clock clock) { return this; } - public Builder serviceEndpoints(List serviceEndpoints) { - this.resource.serviceEndpoints = serviceEndpoints; + public Builder document(DidDocument document) { + this.resource.document = document; return this; } - public Builder serviceEndpoint(Service service) { - this.resource.serviceEndpoints.add(service); - return this; - } - - public Builder verificationMethods(List verificationMethodResources) { - this.resource.verificationMethods = verificationMethodResources; - return this; - } - - public Builder verificationMethod(VerificationMethod method) { - this.resource.verificationMethods.add(method); + public Builder createTimestamp(long createdAt) { + this.resource.createTimestamp = createdAt; return this; } From 38363a615ce16e2cb344ee0b02a5bd5472ad4261 Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Thu, 7 Dec 2023 07:50:08 +0100 Subject: [PATCH 3/4] added package-info --- resources/checkstyle-config.xml | 3 +-- resources/checkstyle-suppressions.xml | 9 -------- resources/suppressions.xml | 10 ++++++++ .../did/spi/DidDocumentPublisher.java | 2 ++ .../edc/identithub/did/spi/package-info.java | 23 +++++++++++++++++++ .../did/spi/store/DidResourceStore.java | 2 ++ 6 files changed, 38 insertions(+), 11 deletions(-) delete mode 100644 resources/checkstyle-suppressions.xml create mode 100644 resources/suppressions.xml create mode 100644 spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/package-info.java diff --git a/resources/checkstyle-config.xml b/resources/checkstyle-config.xml index 308a1386a..97d623b33 100644 --- a/resources/checkstyle-config.xml +++ b/resources/checkstyle-config.xml @@ -29,8 +29,7 @@ - + diff --git a/resources/checkstyle-suppressions.xml b/resources/checkstyle-suppressions.xml deleted file mode 100644 index daca7e6f7..000000000 --- a/resources/checkstyle-suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/resources/suppressions.xml b/resources/suppressions.xml new file mode 100644 index 000000000..b8cebb2b5 --- /dev/null +++ b/resources/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java index 881ba20c7..8595d6777 100644 --- a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/DidDocumentPublisher.java @@ -15,12 +15,14 @@ package org.eclipse.edc.identithub.did.spi; import org.eclipse.edc.iam.did.spi.document.DidDocument; +import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.result.Result; /** * The DidDocumentPublisher is responsible for taking a {@link DidDocument} and making it available at a VDR (verifiable data registry). * For example, an implementation may choose to publish the DID to a CDN. */ +@ExtensionPoint public interface DidDocumentPublisher { /** diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/package-info.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/package-info.java new file mode 100644 index 000000000..804b7892f --- /dev/null +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation + * + */ + + +/** + * This module declares several service interfaces and extension points that are required to host, publish and store + * DID documents. + */ +@Spi(value = "Identity Hub DID services") +package org.eclipse.edc.identithub.did.spi; + +import org.eclipse.edc.runtime.metamodel.annotation.Spi; diff --git a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java index a5231c16e..8541d32ad 100644 --- a/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java +++ b/spi/identity-hub-did-spi/src/main/java/org/eclipse/edc/identithub/did/spi/store/DidResourceStore.java @@ -15,6 +15,7 @@ package org.eclipse.edc.identithub.did.spi.store; import org.eclipse.edc.identithub.did.spi.model.DidResource; +import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint; import org.eclipse.edc.spi.result.StoreResult; import java.util.List; @@ -22,6 +23,7 @@ /** * The DidResourceStore interface provides CRUD methods for interacting with a store of {@link DidResource} objects. */ +@ExtensionPoint public interface DidResourceStore { /** From 9be9686737bfc290c69366daa618654d46113b2b Mon Sep 17 00:00:00 2001 From: Paul Latzelsperger Date: Thu, 7 Dec 2023 08:50:50 +0100 Subject: [PATCH 4/4] pr remark --- .../edc/identityhub/did/DidServicesExtension.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java index 89787baa5..c40f4b6fd 100644 --- a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java +++ b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidServicesExtension.java @@ -14,5 +14,12 @@ package org.eclipse.edc.identityhub.did; -public class DidServicesExtension { +import org.eclipse.edc.runtime.metamodel.annotation.Extension; +import org.eclipse.edc.spi.system.ServiceExtension; + +import static org.eclipse.edc.identityhub.did.DidServicesExtension.NAME; + +@Extension(value = NAME) +public class DidServicesExtension implements ServiceExtension { + public static final String NAME = "DID Service Extension"; }