diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9a1facd6..f2bc6786bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ _**For better traceability add the corresponding GitHub issue number in each cha ### Added - #999 Added notification processing feedback in FE +- #1108 Added concept for policy management enhancement +- #1007 Added data-sovereignty/policy-management section in arc42 documentation - #1190 update notification contracts on policy updates ### Changed diff --git a/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md b/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md new file mode 100644 index 0000000000..9b479ce8af --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/#1108-policy-management-enhancement.md @@ -0,0 +1,635 @@ +# \[Concept\] \[#1108\] Policy management enhancement + +| Key | Value | +|---------------|---------------------------------------------------------------------------| +| Author | @ds-crehm | +| Creation date | 02.07.2024 | +| Ticket Id | [#849](https://github.com/eclipse-tractusx/traceability-foss/issues/1108) | +| State | DRAFT | + +# Table of Contents +1. [Overview](#overview) +2. [Requirements](#requirements) +3. [Concept](#concept) +4. [Additional Details](#additional-details) + +# Overview +It must be possible for users to change policies used for asset provisioning and notifications in the frontend of Trace-X. + +# Requirements +- [ ] Parts can be republished + - [ ] A policy must be selected (chosen from the existing policies) + - [ ] Part will be synchronized automatically afterwards +- [ ] Policy updates trigger an update and synchronization of all related parts +- [ ] When sending notifications, the active policy for the respective BPN is used for contract negotiation +- [ ] User can not create valid, active policies for BPNs that already have a valid, active policy + - [ ] If he wants to do so anyways, the existing policies will be invalidated (validUntil = currentTime). -> Before doing that, a modal will ask him for confirmation. +- [ ] If the EDC of the receiving BPN provides multiple contract offers, Trace-X will check if **any of them** are active and match the own policy definition. In that case, the data will be sent. This applies to data provisioning and notification transmission. +- [ ] After startup, additional policy is created for the own BPN. Its constraints are identical to the default-policy and it will be used for the initial contractOffer creation. +- [ ] contractOffer is only updated when the policy for the own BPN is changed or when a new policy for the own BPN is created. +- [ ] There must always be one policy with the own BPN included. It can not be deleted. The validUntil date for this one should be *null* and cannot be set to a different value. +- [ ] Default-policy is always used for sending notifications, when there is no policy defined for the receiver BPN. + +# Concept + +## When to update policies for parts +A part can be republished with a different policy -> in this case the policy must be updated with the chosen policy and then republished. +For this the policy update process below must be used and then the existing publish-process can be used to republish and synchronize the part. + +When a policy is updated, all parts that used this policy must be updated and republished with the new policy. +In this case, all parts using that policy must be updated. For this Trace-X must iterate through all parts and check if they use the changed policy. +Then the affected parts must have their policies updated. + +## Policy update process for parts +![policy-update.svg](policy-update.svg) + +1. **policyDefinition + globalAssetId** + +The globalAssetId for which the policy must be changed must be provided. And the new policy that should be used must be provided as well. + +2. **query_registry(globalAssetId)** + +The globalAssetId is used to retrieve the aasIdentifier from the registry: + +GET ***registryURL***/semantics/registry/api/v3/lookup/shells?assetIds=eyJuYW1lIjoiZ2xvYmFsQXNzZXRJZCIsInZhbHVlIjoidXJuOnV1aWQ6NmIyMjk2YmItMjZjMC00ZjM4LThhMjItMDkyMzM4YzM2ZTIyIn0%3D + +Header: "Edc-Bpn" = "***BPN***" + +The assetId attached to the URL is the following **base64-encoded**: + +{"name":"globalAssetId","value":"***globalAssetId***"} + +3. **aasIdentifier** + +The registry returns the aasIdentifier as JSON result like this: +```json +{ + "paging_metadata": {}, + "result": [ + "urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54" + ] +} +``` +The aasIdentifier must be cached for future requests. + +4. **get_shell(aasIdentifier)** + +The aasIdentifier is used to retrieve the shell from the registry: + +GET ***registryURL***/semantics/registry/api/v3/shell-descriptors/dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +Header: "Edc-Bpn" = "***BPN***" + +The ID attached to the URL is the aasIdentifier **base64-encoded**: urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54 -> dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +5. **shell** + +The shell is returned as JSON result like this: +```json +{ + "description": [], + "displayName": [], + "globalAssetId": "urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22", + "idShort": "a/devVehicleHybrid-9d2ca28d8896407bbdc9a8f65c381cab", + "id": "urn:uuid:7e29e7e6-71a9-4f81-afc9-8b8434da4b0d", + "specificAssetIds": [ + { + "supplementalSemanticIds": [], + "name": "van", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "supplementalSemanticIds": [], + "name": "partInstanceId", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "supplementalSemanticIds": [], + "name": "manufacturerId", + "value": "BPNL00000003CML1", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + } + ], + "submodelDescriptors": [ + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:cc3d983e-63f3-46be-8b75-74efe2783d11", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart", + "id": "urn:uuid:cc3d983e-63f3-46be-8b75-74efe2783d11", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart" + } + ] + }, + "supplementalSemanticId": [], + "description": [], + "displayName": [] + }, + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:e16f7eaa-21f9-42ef-a38e-32f62a1d5efd", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt", + "id": "urn:uuid:e16f7eaa-21f9-42ef-a38e-32f62a1d5efd", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt" + } + ] + }, + "supplementalSemanticId": [], + "description": [], + "displayName": [] + } + ] +} +``` + +The shell must be cached for future requests. + +6. **get_contractDefinition(shell.subprotocolBodyID)** + +The contractDefinition is retrieved from the EDC using the subprotocolBodyID. +The subprotocolBodyID is taken from the string contained in submodelDescriptors.endpoints.protocolInformation.subprotocolBody. +The ID should be the same for every submodel, so it can be taken from any of them. +In the best case, it should be taken from the submodel of type SerialPart, since that is the default used in every asset. + +POST ***EDC-providerURL***/management/v2/contractdefinitions/request + +JSON body: +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "filterExpression": { + "operandLeft": "assetsSelector.operandRight", + "operator": "=", + "operandRight": "<<>>" + } +} +``` + +7. **contractDefinition** + +The contractDefinition is returned as JSON result like this: +```json +[ + { + "@id": "0f410a5c-b51b-4546-bae2-eacc20483e15", + "@type": "ContractDefinition", + "accessPolicyId": "traceability-core", + "contractPolicyId": "traceability-core", + "assetsSelector": { + "@type": "Criterion", + "operandLeft": "https://w3id.org/edc/v0.0.1/ns/id", + "operator": "=", + "operandRight": "urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892" + }, + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/", + "tx-auth": "https://w3id.org/tractusx/auth/", + "cx-policy": "https://w3id.org/catenax/policy/", + "odrl": "http://www.w3.org/ns/odrl/2/" + } + } +] +``` + +Only the accessPolicyId or the contractPolicyId is needed for the next request. +Since both are always identical at the time of writing, it doesn't matter which one is used. +I decided to use the contractPolicyId. + +8. **get_policyDefinition(contractDefinition.contractPolicyId)** + +The policyDefinition is retrieved from the EDC using the contractPolicyId: + +GET ***EDC-providerURL***/management/v2/policydefinitions/***contractPolicyId*** + +9. **policyDefinition** + +The policyDefinition is returned as JSON result like this: +```json +{ + "@id": "traceability-core", + "@type": "PolicyDefinition", + "createdAt": 1719845712993, + "policy": { + "@id": "c71b6886-b0fa-4348-8006-38d669d61dbc", + "@type": "odrl:Set", + "odrl:permission": { + "odrl:action": { + "odrl:type": "use" + }, + "odrl:constraint": { + "odrl:and": [ + { + "odrl:leftOperand": "cx-policy:FrameworkAgreement", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "traceability:1.0" + }, + { + "odrl:leftOperand": "cx-policy:UsagePurpose", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "cx.core.industrycore:1" + } + ] + } + }, + "odrl:prohibition": [], + "odrl:obligation": [] + }, + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "edc": "https://w3id.org/edc/v0.0.1/ns/", + "tx": "https://w3id.org/tractusx/v0.0.1/ns/", + "tx-auth": "https://w3id.org/tractusx/auth/", + "cx-policy": "https://w3id.org/catenax/policy/", + "odrl": "http://www.w3.org/ns/odrl/2/" + } +} +``` + +10. **compare policies** + +The policy retrieved from the last step and the policy initially provided by the user (Step 1) must be compared. + +If the compared policies in step 10 are identical, nothing must be changed and the process can be finalized (**step 11**). +If the compared policies in step 10 are **not** identical, continue with **step 12**. + +12. **create asset** + +A new policy asset must be created in the EDC: + +POST ***EDC-providerURL***/management/v3/assets + +JSON body: +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "properties": { + "description": "<<>>" + }, + "dataAddress": { + "proxyPath": "true", + "type": "HttpData", + "proxyMethod": "false", + "proxyQueryParams": "false", + "proxyBody": "false", + "baseUrl": "<<>>" + } +} +``` + +The policy description may be omitted as well: + +```json +{ + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "properties": { + }, + "dataAddress": { + "proxyPath": "true", + "type": "HttpData", + "proxyMethod": "false", + "proxyQueryParams": "false", + "proxyBody": "false", + "baseUrl": "https://traceability-e2e-a.dev.demo.catena-x.net" + } +} +``` + +The baseURL must be taken from the currently used instance and environment configuration. +The ID must be cached for the last two requests. + +13. **create new policyDefinition** + +A new policy with the provided data must be created in the EDC: + +POST ***EDC-providerURL***/management/v2/policydefinitions + +JSON body: +```json +{ + "@context": { + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@id": "<<>>", + "policy": { + "@type": "odrl:Set", + "odrl:permission": { + "odrl:action": { + "odrl:type": "use" + }, + "odrl:constraint": { + "odrl:and": [ + { + "odrl:leftOperand": "cx-policy:FrameworkAgreement", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "traceability:1.0" + }, + { + "odrl:leftOperand": "cx-policy:UsagePurpose", + "odrl:operator": { + "@id": "odrl:eq" + }, + "odrl:rightOperand": "cx.core.industrycore:1" + } + ] + } + } + } +} +``` + +The newly created policyDefinition must be taken from the provided policyDefinition (step 1). +The ID must be cached for the next request. + +14. **create new contractDefinition(with new assetID+policyDefinitionID)** + +A new contractDefinition must be created in the EDC using the previously created asset and policyDefinition: + +POST ***EDC-providerURL***/management/v2/contractdefinitions + +JSON body: +```json +{ + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "<<>>", + "accessPolicyId": "<<>>", + "contractPolicyId": "<<>>", + "assetsSelector": { + "operandLeft": "https://w3id.org/edc/v0.0.1/ns/id", + "operator": "=", + "operandRight": "<<>>" + } +} +``` + +15. **update shell(with new subprotocolBodyID)** + +The final step is to update the shell with the newly created asset, which is set to be a contractDefinition that uses the provided policy: + +PUT ***registryURL***/semantics/registry/api/v3/shell-descriptors/dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 + +Header: "Edc-Bpn" = "***BPN***" + +JSON body: +```json +{ + "description": [], + "displayName": [], + "globalAssetId": "urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22", + "idShort": "a/devVehicleHybrid-7f4198785bb64374b984839201f61cd2", + "id": "urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54", + "specificAssetIds": [ + { + "name": "van", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "name": "manufacturerId", + "value": "BPNL00000003CML1", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + }, + { + "name": "partInstanceId", + "value": "OMAOYGBDTSRCMYSCX", + "externalSubjectId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "BPNL00000003CNKC" + } + ] + } + } + ], + "submodelDescriptors": [ + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=<<>>;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart", + "id": "urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.serial_part:3.0.0#SerialPart" + } + ] + }, + "description": [], + "displayName": [] + }, + { + "endpoints": [ + { + "interface": "SUBMODEL-3.0", + "protocolInformation": { + "href": "https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e", + "endpointProtocol": "HTTP", + "endpointProtocolVersion": [ + "1.1" + ], + "subprotocol": "DSP", + "subprotocolBody": "id=<<>>;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net", + "subprotocolBodyEncoding": "plain", + "securityAttributes": [ + { + "type": "NONE", + "key": "NONE", + "value": "NONE" + } + ] + } + } + ], + "idShort": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt", + "id": "urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e", + "semanticId": { + "type": "ExternalReference", + "keys": [ + { + "type": "GlobalReference", + "value": "urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt" + } + ] + }, + "description": [], + "displayName": [] + } + ] +} +``` + +The ID attached to the URL is the aasIdentifier **base64-encoded**: urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54 -> dXJuOnV1aWQ6NjM1YTgyNDItNGE4OS00ODgyLThhNmEtM2E3OGIzNDkyZjU0 +The JSON body is the shell taken from **step 5** with the subprotocolBodyID of all submodelDescriptor endpoints replaced with the assetID from **step 12**. +Additionally, all empty instances of "supplementalSemanticId" must be removed for the request to work. + +An Insomnia collection is provided with the respective requests. (policy-update.json) + +## Policies used for notification process +Whenever a notification is sent, the backend will check for the policy that is configured for the receiving BPN. +If there is an active (validUntil > currentTime) policy, that one will be used for the contract negotation. +If the catalogOffer of the receiving BPN matches with the policy, the notification will be sent. +If not, an error message is created and the notification will not be sent. + +If there are any expired (validUntil <= currentTime) policies configured for the receiving BPN, an error message ('policy has expired') will be created and the notification will **not** be sent. +If there are no policies configured for the receiving BPN, the default policy will be used for the negotiation. + +![notification-policy.svg](notification-policy.svg) + +In the frontend, it should not be possible to create multiple valid policies for the same BPN. +During the creation of policies, all policies that already exist must be checked. +If there is any policy that is already used for the configured BPN, the existing policy will be changed to inactive by setting the validUntil date to the currentTime. +Before doing this the user must be informed about this process and confirm it in a modal. +![notification-policy-modal.png](notification-policy-modal.png) + +## Contract negotiation +During contract negotiation, there can only be one policy definition from Trace-X that will be compared with the catalogOffers from the receiverBPN. +If the receiverBPN provides multiple policies in his catalogOffer, Trace-X will compare its own policy definition with all of them. +If **any of them** are valid **and** match the own policy definition, the data will be sent. + +## Updating the catalogOffer +In order to be able to receive notifications or to share parts, a catalogOffer must be created. +The catalogOffer includes the necessary policy definitions. On startup of Trace-X a default policy is provided. The default policy will be used to create the initial catalogOffer. +When the administrator creates a new policy, the catalogOffer will be recreated with the new policy and the default policy will be deleted. +If the administrator chooses a wrong policy or a wrong BPN for the policy, he might disable the application from receiving notifications. + +This can be avoided by creating a policy that is configured for the own BPN in addition to the default-policy. +This policy will be created on start-up and the initial catalogOffer will be created using it. +When sending notifications in this state the default-policy will be used. + +The catalogOffer will **only** be updated when this policy is changed or when another policy is created for the own BPN (that will replace the initial one). +Creating a policy for other BPNs will not affect the catalogOffer. + +# Additional Details +Given the dynamic nature of ongoing development, there might be variations between the conceptualization and the current implementation. For the latest status, refer to the documentation. diff --git a/docs/concept/#1108-policy-management-enhancement/notification-policy-modal.png b/docs/concept/#1108-policy-management-enhancement/notification-policy-modal.png new file mode 100644 index 0000000000..be650a4396 Binary files /dev/null and b/docs/concept/#1108-policy-management-enhancement/notification-policy-modal.png differ diff --git a/docs/concept/#1108-policy-management-enhancement/notification-policy.puml b/docs/concept/#1108-policy-management-enhancement/notification-policy.puml new file mode 100644 index 0000000000..199bcb1309 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/notification-policy.puml @@ -0,0 +1,39 @@ +@startuml +title + ==Policies for notifications +end title + +autonumber "[00]" + +actor "User" as U order 0 +participant "Trace-X" as TX order 1 +participant "Receiver" as R order 2 + +U -> TX: sendNotification(notificationID, receiverBPN) +activate TX +TX -> R: getCatalogOffer() +R --> TX: catalogOffer +TX -> TX: Extract policies from catalogOffer +TX -> TX: Get configured policy for receiver BPN +alt NO policies found for receiverBPN +TX -> TX: Compare receiver policies with default policy +alt policies match +TX -> R: sendNotification(notificationID, receiverBPN, defaultPolicy) +TX --> U: Success +else policies don't match +TX --> U: Error('Default policy did not match with receiver policy') +end +else VALID policy found +TX -> TX: Compare receiver policies with configured policy +alt policies match +TX -> R: sendNotification(notificationID, receiverBPN, validPolicy) +TX --> U: Success +else policies don't match +TX --> U: Error('Configured policy did not match with receiver policy') +end +else INVALID policy found +TX --> U: Error('Policy has expired') +end +deactivate TX + +@enduml diff --git a/docs/concept/#1108-policy-management-enhancement/notification-policy.svg b/docs/concept/#1108-policy-management-enhancement/notification-policy.svg new file mode 100644 index 0000000000..ce6a2308af --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/notification-policy.svg @@ -0,0 +1 @@ +Policies for notificationsUserUserTrace-XTrace-XReceiverReceiver[01]sendNotification(notificationID, receiverBPN)[02]getCatalogOffer()[03]catalogOffer[04]Extract policies from catalogOffer[05]Get configured policy for receiver BPNalt[NO policies found for receiverBPN][06]Compare receiver policies with default policyalt[policies match][07]sendNotification(notificationID, receiverBPN, defaultPolicy)[08]Success[policies don't match][09]Error('Default policy did not match with receiver policy')[VALID policy found][10]Compare receiver policies with configured policyalt[policies match][11]sendNotification(notificationID, receiverBPN, validPolicy)[12]Success[policies don't match][13]Error('Configured policy did not match with receiver policy')[INVALID policy found][14]Error('Policy has expired') \ No newline at end of file diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.json b/docs/concept/#1108-policy-management-enhancement/policy-update.json new file mode 100644 index 0000000000..ddb1aaf991 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/policy-update.json @@ -0,0 +1 @@ +{"_type":"export","__export_format":4,"__export_date":"2024-07-08T09:34:20.241Z","__export_source":"insomnia.desktop.app:v2023.5.8","resources":[{"_id":"req_c981967d54b042dbafe208c7b6a50edf","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431136336,"created":1719576341118,"url":"{{ _.registry }}/semantics/registry/api/v3/lookup/shells","name":"1 Query Registry by globalAssetId","description":"","method":"GET","body":{},"parameters":[{"name":"assetIds","value":"{% base64 'encode', 'normal', '{\"name\":\"globalAssetId\",\"value\":\"urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22\"}' %}","disabled":false,"id":"pair_f5f3d12fb2224c1d9e577c42128aa3d9"}],"headers":[{"id":"pair_71ae5e562e9c414a82e84220f3c00343","name":"Edc-Bpn","value":"BPNL00000003CNKC","description":""}],"authentication":{},"metaSortKey":-1715858336003,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"wrk_98caad3c0c70421dbe34e55e9d8078de","parentId":null,"modified":1720431114465,"created":1720431114465,"name":"Update policies","description":"","scope":"collection","_type":"workspace"},{"_id":"req_608d45c126ee46ce8330f712428f247f","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431138554,"created":1719576341210,"url":"{{ _.registry }}/semantics/registry/api/v3/shell-descriptors/{% base64 'encode', 'normal', 'urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54' %}","name":"2 GetShell by aasIdentifier","description":"","method":"GET","body":{},"parameters":[],"headers":[{"id":"pair_7877c58fd3ae46758cabf9f6cb397818","name":"Edc-Bpn","value":"BPNL00000003CNKC","description":"","disabled":false}],"authentication":{},"metaSortKey":-1715858335953,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_d33ec33d40f0402bb68da9612c7ea90e","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431140687,"created":1719578461432,"url":"{{ _.edc_provider_own }}/management/v2/contractdefinitions/request","name":"3 GetContractDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"@vocab\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"filterExpression\": {\n\t\t\"operandLeft\": \"assetsSelector.operandRight\",\n\t\t\"operator\": \"=\",\n\t\t\"operandRight\": \"urn:uuid:fe4f0797-a650-451b-a17e-09ce79c13892\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335928,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_ddfb26a9ff864867b2a7015cec5741a8","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431142594,"created":1719578623696,"url":"{{ _.edc_provider_own }}/management/v2/policydefinitions/traceability-core","name":"4 GetPolicyDefinition","description":"","method":"GET","body":{"mimeType":"application/json","text":""},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335915.5,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_0f8c9b91a06041bf9b3066448bc0ced5","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431144604,"created":1688069768394,"url":"{{ _.edc_provider_own }}/management/v3/assets","name":"5 CreateAsset","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"@vocab\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"@id\": \"policy-test-asset\",\n\t\"properties\": {\n\t},\n\t\"dataAddress\": {\n\t\t\"proxyPath\": \"true\",\n\t\t\"type\": \"HttpData\",\n\t\t\"proxyMethod\": \"false\",\n\t\t\"proxyQueryParams\": \"false\",\n\t\t\"proxyBody\": \"false\",\n\t\t\"baseUrl\": \"https://traceability-e2e-a.dev.demo.catena-x.net\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335909.25,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_86e748b071974201be2ba737e3b55c93","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431147018,"created":1688067318173,"url":"{{ _.edc_provider_own }}/management/v2/policydefinitions","name":"6 CreatePolicyDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"odrl\": \"http://www.w3.org/ns/odrl/2/\"\n\t},\n\t\"@id\": \"policy-test\",\n\t\"policy\": {\n\t\t\"@type\": \"odrl:Set\",\n\t\t\"odrl:permission\": {\n\t\t\t\"odrl:action\": {\n\t\t\t\t\"odrl:type\": \"use\"\n\t\t\t},\n\t\t\t\"odrl:constraint\": {\n\t\t\t\t\"odrl:and\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:leftOperand\": \"cx-policy:FrameworkAgreement\",\n\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"odrl:rightOperand\": \"traceability:1.0\"\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"odrl:leftOperand\": \"cx-policy:UsagePurpose\",\n\t\t\t\t\t\t\"odrl:operator\": {\n\t\t\t\t\t\t\t\"@id\": \"odrl:eq\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"odrl:rightOperand\": \"cx.core.industrycore:1\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335906.125,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_62799f6e9bf54e0dbc937e928e3d9682","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431149000,"created":1688111070053,"url":"{{ _.edc_provider_own }}/management/v2/contractdefinitions","name":"7 CreateContractDefinition","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"@context\": {\n\t\t\"edc\": \"https://w3id.org/edc/v0.0.1/ns/\"\n\t},\n\t\"@id\": \"policy-test-contractdefinition\",\n\t\"accessPolicyId\": \"policy-test\",\n\t\"contractPolicyId\": \"policy-test\",\n\t\"assetsSelector\": {\n\t\t\"operandLeft\": \"https://w3id.org/edc/v0.0.1/ns/id\",\n\t\t\"operator\": \"=\",\n\t\t\"operandRight\": \"policy-test-asset\"\n\t}\n}"},"parameters":[],"headers":[{"id":"pair_e91fcc496b5744beb35d556b287863c3","name":"Content-Type","value":"application/json","description":"","disabled":false},{"id":"pair_282f3617e19e4ae3b82be34a5f423e26","name":"X-Api-Key","value":"{{ _.edc_api_auth_key_dev }}","description":""}],"authentication":{"type":"oauth2","grantType":"client_credentials","accessTokenUrl":"{{ _.base_url_central_idp}}/auth/realms/CX-Central/protocol/openid-connect/token","clientId":"{{ _.client_id }}","clientSecret":"{{ _.client_secret }}"},"metaSortKey":-1715858335904.5625,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_b3051df9f2214b7db09cdf06deafd9c5","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431151270,"created":1719579937454,"url":"{{ _.registry }}/semantics/registry/api/v3/shell-descriptors/{% base64 'encode', 'normal', 'urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54' %}","name":"8 Update Shell","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n\t\"description\": [],\n\t\"displayName\": [],\n\t\"globalAssetId\": \"urn:uuid:6b2296cc-26c0-4f38-8a22-092338c36e22\",\n\t\"idShort\": \"a/devVehicleHybrid-7f4198785bb64374b984839201f61cd2\",\n\t\"id\": \"urn:uuid:635a8242-4a89-4882-8a6a-3a78b3492f54\",\n\t\"specificAssetIds\": [\n\t\t{\n\t\t\t\"name\": \"van\",\n\t\t\t\"value\": \"OMAOYGBDTSRCMYSCX\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"manufacturerId\",\n\t\t\t\"value\": \"BPNL00000003CML1\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"name\": \"partInstanceId\",\n\t\t\t\"value\": \"OMAOYGBDTSRCMYSCX\",\n\t\t\t\"externalSubjectId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"BPNL00000003CNKC\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"submodelDescriptors\": [\n\t\t{\n\t\t\t\"endpoints\": [\n\t\t\t\t{\n\t\t\t\t\t\"interface\": \"SUBMODEL-3.0\",\n\t\t\t\t\t\"protocolInformation\": {\n\t\t\t\t\t\t\"href\": \"https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da\",\n\t\t\t\t\t\t\"endpointProtocol\": \"HTTP\",\n\t\t\t\t\t\t\"endpointProtocolVersion\": [\n\t\t\t\t\t\t\t\"1.1\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"subprotocol\": \"DSP\",\n\t\t\t\t\t\t\"subprotocolBody\": \"id=policy-test-asset;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net\",\n\t\t\t\t\t\t\"subprotocolBodyEncoding\": \"plain\",\n\t\t\t\t\t\t\"securityAttributes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"NONE\",\n\t\t\t\t\t\t\t\t\"key\": \"NONE\",\n\t\t\t\t\t\t\t\t\"value\": \"NONE\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"idShort\": \"urn:samm:io.catenax.serial_part:3.0.0#SerialPart\",\n\t\t\t\"id\": \"urn:uuid:8e1ecd87-fef6-4351-a2d1-4b916ed2d4da\",\n\t\t\t\"semanticId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"urn:samm:io.catenax.serial_part:3.0.0#SerialPart\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"description\": [],\n\t\t\t\"displayName\": []\n\t\t},\n\t\t{\n\t\t\t\"endpoints\": [\n\t\t\t\t{\n\t\t\t\t\t\"interface\": \"SUBMODEL-3.0\",\n\t\t\t\t\t\"protocolInformation\": {\n\t\t\t\t\t\t\"href\": \"https://trace-x-edc-e2e-a-dataplane.dev.demo.catena-x.net/api/public/urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e\",\n\t\t\t\t\t\t\"endpointProtocol\": \"HTTP\",\n\t\t\t\t\t\t\"endpointProtocolVersion\": [\n\t\t\t\t\t\t\t\"1.1\"\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"subprotocol\": \"DSP\",\n\t\t\t\t\t\t\"subprotocolBody\": \"id=policy-test-asset;dspEndpoint=https://trace-x-edc-e2e-a.dev.demo.catena-x.net\",\n\t\t\t\t\t\t\"subprotocolBodyEncoding\": \"plain\",\n\t\t\t\t\t\t\"securityAttributes\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"type\": \"NONE\",\n\t\t\t\t\t\t\t\t\"key\": \"NONE\",\n\t\t\t\t\t\t\t\t\"value\": \"NONE\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"idShort\": \"urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt\",\n\t\t\t\"id\": \"urn:uuid:877c79ef-6279-49f2-9d2b-bcc7e1f5f28e\",\n\t\t\t\"semanticId\": {\n\t\t\t\t\"type\": \"ExternalReference\",\n\t\t\t\t\"keys\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"type\": \"GlobalReference\",\n\t\t\t\t\t\t\"value\": \"urn:samm:io.catenax.single_level_bom_as_built:3.0.0#SingleLevelBomAsBuilt\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"description\": [],\n\t\t\t\"displayName\": []\n\t\t}\n\t]\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json","id":"pair_4defbf48f3c64e9da238cb4ef843b43d"},{"name":"Edc-Bpn","value":"BPNL00000003CNKC","id":"pair_10710d07198e47bc8e2b55555a93e649"}],"authentication":{},"metaSortKey":-1715858335903.7812,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_5c484adc4b9ba8982d565e3bcbd5dcbdc4c2e63b","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431114487,"created":1720431114487,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1720431114487,"_type":"environment"},{"_id":"jar_5c484adc4b9ba8982d565e3bcbd5dcbdc4c2e63b","parentId":"wrk_98caad3c0c70421dbe34e55e9d8078de","modified":1720431114559,"created":1720431114559,"name":"Default Jar","cookies":[],"_type":"cookie_jar"}]} diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.puml b/docs/concept/#1108-policy-management-enhancement/policy-update.puml new file mode 100644 index 0000000000..53e49d1239 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/policy-update.puml @@ -0,0 +1,44 @@ +@startuml +title + ==Policy update +end title + +autonumber "[00]" + +actor "User" as U order 0 +participant "Trace-X" as TX order 1 +participant "Registry" as R order 2 +participant "EDC" as EDC order 3 + +U -> TX: policyDefinition + globalAssetId +activate TX +TX -> R: query_registry(globalAssetId) +activate R +R --> TX: aasIdentifier +deactivate R +TX -> R: get_shell(aasIdentifier) +activate R +R --> TX: shell +deactivate R +TX -> EDC: get_contractDefinition(shell.subprotocolBodyID) +activate EDC +EDC --> TX: contractDefinition +deactivate EDC +TX -> EDC: get_policyDefinition(contractDefinition.contractPolicyId) +activate EDC +EDC --> TX: policyDefinition +deactivate EDC +TX -> TX: compare policies +alt Policies match +TX --> U: Done without changes +else Policies don't match +TX -> EDC: create asset +TX -> EDC: create new policyDefinition +TX -> EDC: create new contractDefinition(with new assetID+policyDefinitionID) +TX -> R: update_shell(with new subprotocolBodyID) +TX --> U: Done with policy update +deactivate TX +end + + +@enduml diff --git a/docs/concept/#1108-policy-management-enhancement/policy-update.svg b/docs/concept/#1108-policy-management-enhancement/policy-update.svg new file mode 100644 index 0000000000..5f48bd5e19 --- /dev/null +++ b/docs/concept/#1108-policy-management-enhancement/policy-update.svg @@ -0,0 +1 @@ +Policy updateUserUserTrace-XTrace-XRegistryRegistryEDCEDC[01]policyDefinition + globalAssetId[02]query_registry(globalAssetId)[03]aasIdentifier[04]get_shell(aasIdentifier)[05]shell[06]get_contractDefinition(shell.subprotocolBodyID)[07]contractDefinition[08]get_policyDefinition(contractDefinition.contractPolicyId)[09]policyDefinition[10]compare policiesalt[Policies match][11]Done without changes[Policies don't match][12]create asset[13]create new policyDefinition[14]create new contractDefinition(with new assetID+policyDefinitionID)[15]update_shell(with new subprotocolBodyID)[16]Done with policy update \ No newline at end of file diff --git a/docs/src/docs/arc42/runtime-view/data-provisioning.adoc b/docs/src/docs/arc42/runtime-view/data-provisioning.adoc index ef9321e8e1..c7a3dcfa3b 100644 --- a/docs/src/docs/arc42/runtime-view/data-provisioning.adoc +++ b/docs/src/docs/arc42/runtime-view/data-provisioning.adoc @@ -1,4 +1,4 @@ -= Data Provisioning += Data provisioning This sequence diagrams describes the process of importing data from a Trace-X dataformat diff --git a/docs/src/docs/arc42/runtime-view/data-sovereignty.adoc b/docs/src/docs/arc42/runtime-view/data-sovereignty.adoc index 761f08fe31..9564c1c559 100644 --- a/docs/src/docs/arc42/runtime-view/data-sovereignty.adoc +++ b/docs/src/docs/arc42/runtime-view/data-sovereignty.adoc @@ -1,3 +1,4 @@ = Data sovereignty -include::data-sovereignty/return_asset_contracts.adoc[leveloffset=+1] +include::data-sovereignty/return-asset-contracts.adoc[leveloffset=+1] +include::data-sovereignty/policy-management.adoc[leveloffset=+1] diff --git a/docs/src/docs/arc42/runtime-view/data-sovereignty/policy-management.adoc b/docs/src/docs/arc42/runtime-view/data-sovereignty/policy-management.adoc new file mode 100644 index 0000000000..a305aa0e81 --- /dev/null +++ b/docs/src/docs/arc42/runtime-view/data-sovereignty/policy-management.adoc @@ -0,0 +1,140 @@ += Policy management + +To ensure data sovereignty within Trace-X, companies can create policies with constraints to ensure that their data is only shared with companies that match their requirements. + +Policies will be used by the EDC to initiate contract negotiations. During the negotiation the EDC will compare the policies of both companies. Only if both policies are valid and the included constraints match, the data will be shared. This applies for sending and receiving of notifications and parts. + +After deploying Trace-X, no policies are defined for any BPNs yet. Instead, Trace-X will set up default policies. This ensures that the basic functionality of Trace-X works. +However, to be sure that data is shared only with companies that match one's requirements, an administrator must set up policies before sending and receiving data. + +The policies used for sending and receiving notifications and parts have an identical data format, so they can be used for each process interchangeably. +The processes itself are different and will be explained here: + +== Policies for sending and receiving parts +[plantuml, target=level-1, format=svg] +.... +include::../../../../uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-publishing-assets.puml[] +.... + +[cols="1,5"] +|=== +|1, 2 +|Policies can be created by administrators at any time in the administration section of Trace-X. + +|3 +|Parts can be imported at any time in the parts section of Trace-X. They will be stored locally at first. + +|4 +|Before connected BPNs can access the imported parts, the parts must be published to the EDC and to the Digital Twin Registry (DTR). + +|5 +|The user must choose the policy that is used for contract negotiation of the selected parts. + +|6 +|The policy is created in the EDC. + +|7 +|Each part is created as a shell in the DTR. This holds all the data of the part. + +|8 +|The created part is linked to the policy from the EDC. This is the last step of data provisioning. Trace-X A has done everything to ensure that companies that have a matching policy can access its published parts. + +|9 +|Trace-X B wants to synchronize parts and retrieve available ones from connected BPNs. In this case Trace-X A and Trace-X B have an established connection. + +|10 +|For part synchronization the Item Relationship Service (IRS) is requested. + +|11 +|First the IRS must know the policies that are used by Trace-X B, so it requests them directly. + +|12 +|Trace-X B returns a list of the configured policies depending on the configuration done by the administrator in step 2. + +|13 +|The IRS requests the catalog from Trace-X A. In the catalog, all policies of Trace-X A are stored. + +|14 +|The EDC of Trace-X A provides the catalog. + +|15 +|The IRS checks the catalog for the required policies and extracts them. + +|16 +|Now that the IRS has all the relevant policies of both companies, it can start comparing the linked policy of each part to the policy list of Trace-X B. This works by comparing the included constraints logically. If no policy matches for a part, it will not be imported. + +|17, 18 +|If the policy of the part matches with any policy of Trace-X A, a contract agreement is created for both Trace-X A and Trace-X B. It can be viewed in the administration section of Trace-X and documents the data exchange. + +|19 +|Now that the contract negotiation was successful, the data consumption process can take place for that part. +|=== + +It's possible to publish parts with different policies. For this, the user must only publish a limited selection of parts for which he can select a policy. For the parts that must be published with different policies, the user can repeat the process. + +**[Work-in-progress]** The user may also choose parts that have already been published - they can be republished with a different policy. The process for this is identical to the regular publishing process. + +== Policies for sending and receiving notifications +[plantuml, target=level-1, format=svg] +.... +include::../../../../uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications.puml[] +.... + +[cols="1,5"] +|=== +|1 +|Policies can be created by administrators at any time in the administration section of Trace-X. In order for policies to be used for notifications the administrator must pay attention to the BPN selection of the policies, as Trace-X will choose notification policies based on that. + +|2 +|The user sends a notification to a connected BPN. + +|3 +|First Trace-X checks the configured policies for any valid (not expired) policies that have the BPN of the receiver in their BPN selection. **There can only be one valid policy for each BPN.** + +|4 +|Trace-X takes the appropriate policyDefinition. + +|5 +|Trace-X requests the catalog of the receiver BPN from their EDC. The catalog contains all policies of the BPN including the policies they use for sending and receiving policies. + +|6 +|The receiver EDC returns the catalog. + +|7 +|Trace-X extracts the required policy definition for receiving notifications from the catalog. If the receiving BPN has multiple valid ones, they all will be extracted in a list. + +|8 +|Trace-X compares the extracted policies with its own policy definition. This works by comparing the included constraints logically. + +|9, 10 +|If any of the policies match, a contract agreement is created and shared with the receiving EDC and the EDC of the sender. It can be viewed in the administration section of Trace-X. + +|11 +|Finally, the notification will be sent to the receiving EDC. + +|12 +|If no policies match, an error will be returned to the user. +|=== + +=== No policies when sending notifications +[plantuml, target=level-1, format=svg] +.... +include::../../../../uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-change.puml[] +.... + +If no policies are configured for the receiving BPN and a notification is sent to that BPN, the default policy of Trace-X is used as a backup. If the default policy is accepted by the receiving BPN, the process can continue as normally and the notification can be sent. When the policy does not match and the notification can't be sent, an administrator can create policies for the receiving BPN. Then the notification can be resent and will use the new policy. + +=== Expired policy when sending notifications +[plantuml, target=level-1, format=svg] +.... +include::../../../../uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-expired.puml[] +.... + +Policies always have an expiration time. When a notification is sent and there are policies configured for the selected BPN with an expiration time in the past, Trace-X will throw an error. In that case, an administrator must either update the policy. Then the policy can be resent. + +=== Testing policies +In order to test the functionality of policies, an administrator can create a policy with test constraints for connected BPNs. When sending notifications to that BPN, the process should be blocked. + +To fix it, the administrator either has to replace the policy with a valid policy or the connected BPN can create an identical policy with the same test constraints. Sending the notification will work after this was done. + +The same applies for sending and receiving parts only then the user must choose the created test policy manually. diff --git a/docs/src/docs/arc42/runtime-view/data-sovereignty/return_asset_contracts.adoc b/docs/src/docs/arc42/runtime-view/data-sovereignty/return-asset-contracts.adoc similarity index 100% rename from docs/src/docs/arc42/runtime-view/data-sovereignty/return_asset_contracts.adoc rename to docs/src/docs/arc42/runtime-view/data-sovereignty/return-asset-contracts.adoc diff --git a/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-change.puml b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-change.puml new file mode 100644 index 0000000000..6687dcb45a --- /dev/null +++ b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-change.puml @@ -0,0 +1,34 @@ +@startuml +'https://plantuml.com/sequence-diagram +autonumber +title Policies: Sending notifications without policies + +actor Admin +actor User +participant "Trace-X" as TraceX +participant "Receiver EDC" as EDC + +Admin -> TraceX: create policies +... +User -> TraceX: send notification to receiver BPN +activate TraceX +TraceX -> EDC: get catalog of receiver BPN +activate EDC +EDC --> TraceX: catalog +deactivate EDC +TraceX -> TraceX: extract required policy definition from catalog +TraceX -> TraceX: get own policy definition for receiver BPN +activate TraceX +TraceX --> TraceX: no policyDefinition for receiver BPN -> use default policy +deactivate TraceX +TraceX -> TraceX: compare policy definition with own default policy +alt policies don't match +TraceX --> User: error: policies don't match +deactivate TraceX +... +Admin -> TraceX: add policy for receiver BPN +... +User -> TraceX: resend notification to receiver BPN +ref over User, Admin, TraceX, EDC: send notification +end +@enduml diff --git a/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-expired.puml b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-expired.puml new file mode 100644 index 0000000000..a46c1a3956 --- /dev/null +++ b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications-policy-expired.puml @@ -0,0 +1,32 @@ +@startuml +'https://plantuml.com/sequence-diagram +autonumber +title: Policies: Sending notifications with expired policy + +actor Admin +actor User +participant "Trace-X" as TraceX +participant "Receiver EDC" as EDC + +Admin -> TraceX: create policies +... +User -> TraceX: send notification to receiver BPN +activate TraceX +TraceX -> EDC: get catalog of receiver BPN +activate EDC +EDC --> TraceX: catalog +deactivate EDC +TraceX -> TraceX: extract required policy definition from catalog +TraceX -> TraceX: get own policy definition for receiver BPN +activate TraceX +TraceX --> TraceX: expired policyDefinition +deactivate TraceX +TraceX --> User: error: policy expired +deactivate TraceX +... +Admin -> TraceX: update policy +... +User -> TraceX: resend notification to receiver BPN +ref over User, Admin, TraceX, EDC: send notification +deactivate TraceX +@enduml diff --git a/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications.puml b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications.puml new file mode 100644 index 0000000000..f79b9341d0 --- /dev/null +++ b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-notifications.puml @@ -0,0 +1,33 @@ +@startuml +'https://plantuml.com/sequence-diagram +autonumber +title Policies: Send notification + +actor Admin +actor User +participant "Trace-X A" as TXA +participant "EDC A" as EDCA +participant "EDC B" as EDCB + +Admin -> TXA: create policies +... +User -> TXA: send notification to receiver BPN +activate TXA +TXA -> EDCB: get catalog of receiver BPN +activate EDCB +EDCB --> TXA: catalog +deactivate EDCB +TXA -> TXA: extract required policy definition from catalog +TXA -> TXA: get own policy definition for receiver BPN +activate TXA +TXA --> TXA: valid policyDefinition +deactivate TXA +TXA -> TXA: compare policy definitions +alt policies match +TXA --> EDCB: contract agreement +TXA --> EDCA: contract agreement +TXA -> EDCB: send notification +else +TXA --> User: error: policies don't match +end +@enduml diff --git a/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-publishing-assets.puml b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-publishing-assets.puml new file mode 100644 index 0000000000..3264dce3f9 --- /dev/null +++ b/docs/src/uml-diagrams/arc42/runtime-view/data-sovereignty/data-sovereignty-publishing-assets.puml @@ -0,0 +1,52 @@ +@startuml +'https://plantuml.com/sequence-diagram +autonumber +title Policies: Send and receive parts + +actor "Admin A" as AA +actor User +participant "Trace-X A" as TXA +participant "DTR A" as DTRA +participant "EDC A" as EDCA +participant "IRS B" as IRSB +participant "EDC B" as EDCB +participant "Trace-X B" as TXB +actor "Admin B" as AB + +AA -> TXA: create policies +AB -> TXB: create policies +... +User -> TXA: import parts +... +User -> TXA: publish selected parts +activate TXA +User --> TXA: select policy to be used +TXA -> EDCA: create policy +loop selected parts +TXA -> DTRA: create part +TXA -> DTRA: link part and policy +end +deactivate TXA +... +TXB -> TXB: synchronize parts +activate TXB +TXB -> IRSB: start contract negotiation +activate IRSB +IRSB -> EDCA: get catalog of Trace-X A +activate EDCA +EDCA --> IRSB: catalog +deactivate EDCA +IRSB -> IRSB: extract policy definitions from catalog +IRSB -> TXB: get configured policies +activate TXB +TXB --> IRSB: policies +deactivate TXB +loop each part +IRSB -> IRSB: compare linked policy definition with own policy list +alt policies match +IRSB --> EDCA: contract agreement +IRSB --> EDCB: contract agreement +ref over IRSB, TXB: data consumption +end +end +@enduml diff --git a/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-notifications.puml b/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-notifications.puml index 3a19bb88f4..5b104ec138 100644 --- a/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-notifications.puml +++ b/docs/src/uml-diagrams/arc42/runtime-view/policies/policy-notifications.puml @@ -23,7 +23,7 @@ TraceX -> TraceX: Validate contract type, method and policy alt Notification type: Alert TraceX -> TraceX: Filter for method (update, receive) - TraceX -> TraceXIRSLib: Validate if catalog policy matches the configured policies in IRS Lib (3 default policies) + TraceX -> TraceXIRSLib: Validate if catalog policy matches the configured policy for the receiver activate TraceXIRSLib TraceXIRSLib --> TraceX: Valid deactivate TraceXIRSLib @@ -48,7 +48,7 @@ alt Notification type: Alert end else Notification Type: Investigation TraceX -> TraceX: Filter for method (update, receive) - TraceX -> TraceXIRSLib: Validate if catalog policy matches the configured policies in IRS Lib (3 default policies) + TraceX -> TraceXIRSLib: Validate if catalog policy matches the configured policy for the receiver activate TraceXIRSLib TraceXIRSLib --> TraceX: Valid deactivate TraceXIRSLib