Developing with the DT KIT
Digital Twin KIT
Architecture Overview
The interplay of the Digital Twin Kit's components can be found in the Operation View.
API Specifications
All openAPI-specifications for the Digital Twin Kit services are rendered in the section of these docs
Asset Administration Shell
The Asset Administration Shell (AAS) is a specification that is released by the Industrial Digital Twin Association (IDTA) with a perspective to be adopted by the International Electrotechnical Commission (IEC) as IEC 63278.
Its mission is defining how “information about assets […] can be exchanged in a meaningful way between partners in a value creation network” (IDTA 01001-3-0 , p.12) . As such, it is well-suited to contribute to the toolbox of Catena-X. While the Spec offers an extensive suite of meta-model elements and APIs, Catena-X only mandates a small subset that is defined in CX - 0002.
Submodels
An Asset Administration Shell is organized in Submodels. Each Submodel represents a self-contained aspect of an asset - typical examples are the PartAsPlanned or SingleLevelBomAsBuilt (which denotes the hierarchical composition of parts into a whole). All relevant Submodels for Catena-X can be are built from SAMM models and can be found on Github. As different aspects of an Asset may be known to different parties on the value-chain, Submodels for a single asset must be capable to run independently of each other. The specification explicitly allows this, enabling easy cross-company data integration.
Recognizing that not all use-cases require the full functionality of the AAS-Spec, Catena-X demands that Data
Providers offer only a subset of the SubmodelServiceSpecification - namely the $value
serialization. This is an
abbreviated notation of an AAS-Submodel that is focused on data instead of context. While it is advisable to expose
Submodels with help of a full-fletched AAS-server SDK that provides the content-modifiers and API-endpoints
out-of-the-box, this is not yet mandatory.
Digital Twin Registry
What Catena-X calls the "Digital Twin Registry" (DTR) is actually the union of two different services that the AAS specification has specified. For the sake of simplicity, they are both defined in a single component. The DTR serves a similar function as the index in a book: When trying to discover information, it's convenient to have an overview WHAT one will find, HOW and WHERE to access it. The registry caters exactly that information: For every asset it knows, it holds a number of Submodel Descriptors and in these, a consumer app will find information what it will find (via the semanticId) and how to access the information ( endpoint, security setup etc.). As the information contained in the DTR may be sensitive and not be trusted with a central entity, every data provider must offer his own DTR as an EDC Data Asset. While it is only mandatory to implement the GET endpoints as specified in the Development View, data providers may find it useful to implement other requests for registration on top. Either way, they are free to populate their DTR in any way they desire.
Catena-X specific Services
DTRs hold sensitive information: a submodel-descriptor may not give access to the actual Submodel-data but all in cumulo hint at production volumes as each Twin represents an asset. Therefore, Catena-X implements decentral DTRs (DDTR), each running with a business partner. In an IDTA-Whitepaper, several high-level concepts for DDTRs are introduced. The AAS-specification remains agnostic to the approaches and endorses none of them. Catena-X must deal with the additional complexity that stems from the interaction with the EDC.
Leveraging the native capabilities of the EDC and the EDC Discovery Service, Catena-X uses a discovery pattern that has
the same capability as a central Digital Twin Registry would:
It allows to start a Discovery Process with only an assetId and its type (like manufacturerPartId
).
However, in Catena-X some of the data is deemed so sensitive that a central authority can't be
trusted with it. Thus, a decentralized approach is implemented: each Data Provider will run their own DTR.
This poses a challenge for discovery if the BPN of the supplier is not known by the data consumer. After all, a
Data Consumer must still find out the address where to fetch the data from. That's why Catena-X has introduced a
three-step discovery pattern made up of the central microservices Discovery Finder, BPN Discovery (or several of them)
and finally the EDC discovery that is part of the CX-Portal.
The Discovery Finder and the BPN Discovery service are described as part of this Kit.
Sample Data
Generic sample data for relevant data objects is contained in the openAPI-specs of the respective services. This chapter contains data structures that are more specifically designed for use in the Digital Twin Kit. They are compliant with the base-specifications (like AAS) but restrict the application even further for use in this Dataspace.
Registration at Digital Twin Registry
The Digital Twin Registry connects an asset (identified by its assetIds) with links to the Submodels. Since Catena-X
uses the EDC as a gateway for all inter-company interaction, the Digital Twin Registry must account for that. By
design, it includes the possibility to add additional context via the fields subprotocol
, subprotocolBody
and
subprotocolEncoding
. subprotocol
will always be set to DSP
, short for the Dataspace Protocol as
standardized by the IDSA. subprotocolEncoding
is always set to plain
.
There's three relevant inputs to discover a referenced Submodel in Catena-X:
The
subprotocolBody
contains two pieces of information, assigned with=
and separated by;
:dspEndpoint
is the URL of the Control Plane where a Data Consumer can negotiate for access to this Submodel. For many connector-implementations, this will end on/api/v1/dsp
. As this property will be used in the discovery sequence to construct acatalog
-request, this variable is equivalent to the<base>
in this example in the DSP-spec.When calling the /catalog API of that Control Plane, a Consumer should filter for
dcat:Dataset
entries that are identified by theid
mentioned in thesubprotocolBody
. For communication between two EDCs, the Consumer could query with the following payload:{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/"
},
"@type": "CatalogRequest",
"counterPartyAddress": "{{provider-dsp-endpoint}}",
"protocol": "dataspace-protocol-http",
"querySpec": {
"offset": 0,
"limit": 50,
"filterExpression": [
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/"
},
"@type": "edc:Criterion",
"operandLeft": "https://w3id.org/edc/v0.0.1/ns/id",
"operator": "=",
"operandRight": "{{assetId}}"
}
]
}
}
After having successfully negotiated for a Data Offer associated with the
id
, the Data Consumer can query the Data Plane of the given EDC to access the data. For that, the Provider must use the URL given in the Submodel-Descriptor'shref
field and append the additional URL-segment/$value
.In some circumstances (such as the PCF Kit) the
submodelDescriptors[i]/endpoints[j]/interface
property may be used to signify that the payload of the Submodel must be retrieved using an API that's not the subset of Submodel-API defined in CX-0002. This leaves the scope of the DT Kit and must be specified by subsequent standards.
A full example on the default case is shown in the next section.
Registering a new Twin
Registration of a new twin is (at least in Catena-X) equivalent to the creation of a new twin. Thus, a Data Provider should always ensure that there is no AAS-descriptor created for the respective assetIds yet. If there already is one, the submodel-descriptor should be added to the existing shell-descriptor.
POST /shell-descriptors
{
"id": "urn:uuid:e5c96ab5-896a-1234-8761-efd74777ca97",
"idShort": "myAas",
"specificAssetIds": [
{
"name": "manufacturerPartId",
"value": "123-345-567103",
"externalSubjectId": {
"type": "ExternalReference",
"keys": [
{
"type": "GlobalReference",
"value": "{{BPN of the party privileged}}"
}
]
}
}
],
"submodelDescriptors": [
{
"id": "e5c96ab5-896a-482c-8761-efd74777ca97",
"semanticId": {
"type": "ExternalReference",
"keys": [
{
"type": "GlobalReference",
"value": "urn:bamm:io.catenax.material_for_recycling:1.1.0#MaterialForRecycling"
}
]
},
"endpoints": [
{
"interface": "SUBMODEL-3.0",
"protocolInformation": {
"href": "https://edc.data.plane/mypath/submodel",
"endpointProtocol": "HTTP",
"endpointProtocolVersion": [
"1.1"
],
"subprotocol": "DSP",
"subprotocolBody": "id=123;dspEndpoint=http://edc.control.plane/api/v1/dsp",
"subprotocolBodyEncoding": "plain",
"securityAttributes": [
{
"type": "NONE",
"key": "NONE",
"value": "NONE"
}
]
}
}
]
}
]
}
Registering a new Submodel at an existing Twin
POST /shell-descriptors/{{aasId}}
{
"id": "e5c96ab5-896a-482c-8761-efd74777ca97",
"semanticId": {
"type": "ExternalReference",
"keys": [
{
"type": "GlobalReference",
"value": "urn:bamm:io.catenax.material_for_recycling:1.1.0#MaterialForRecycling"
}
]
},
"endpoints": [
{
"interface": "SUBMODEL-3.0",
"protocolInformation": {
"href": "https://edc.data.plane/mypath/submodel",
"endpointProtocol": "HTTP",
"endpointProtocolVersion": [
"1.1"
],
"subprotocol": "DSP",
"subprotocolBody": "id=123;dspEndpoint=http://edc.control.plane/api/v1/dsp",
"subprotocolBodyEncoding": "plain",
"securityAttributes": [
{
"type": "NONE",
"key": "NONE",
"value": "NONE"
}
]
}
}
]
}
Registration at EDC
Integration between the EDC and AAS-Components in the dataspace is a strict prerequisite for robust discovery and data access in the Catena-X dataspace. As all data that crosses company-boundaries must be exchanged via an EDC, CX-0002 provides the necessary normative statements to facilitate interoperable data exchange.
One relevant question is how the EDC-shielded services of this Kit should register with the Asset endpoint of the EDC Management API. While the EDC's /v3/assets endpoint is internal to the Data Provider only, the objects are also available via the /catalog API that is specified in the Dataspace Protocol.
The EDC uses json-ld. Json-ld is a serialization for RDF graphs (see Resource Description Framework).
The json-ld @context
section can declare the namespaces that resources explicitly mentioned in the rest of the
document belong to. It may also define default namespace with @vocab
for resources without explicitly stated
namespaces. Outside of the "@context" section, the @type
property always defines the class that an object belongs to.
As stated in the openAPI-specification of the EDC Management API's relevant endpoint, all entries in the
properties
object and the privateProperties
object can be chosen freely. The section on the dataAddress
is
structured depending on the edc:type
property. The example below is determined by the HttpDataAddress
class. Its parameters determine the behavior of the EDC's HTTP data plane at runtime. How they should be used is not
subject to standardization since they aren't visible in the Dataspace. Certain values may have to be set in a certain
way to enable the data exchange via the DT Kit.
It presents the backend resources as dcat:Dataset
s with properties funnelled through from the assets-API. These
properties can be freely set by the Data Provider.
For successful discovery of Digital Twins, it is critical to register Submodels and Digital-Twin-Registries in a
harmonized way. The following overview shall explain how the properties
section could be used.
http://purl.org/dc/terms/type
(mandatory as per CX-0018): denotes the type of Asset that is registered. The property points to an RDF resource. In the context of digital twins two predefined resources are of relevance:https://w3id.org/catenax/taxonomy#DigitalTwinRegistry
andhttps://w3id.org/catenax/taxonomy#Submodel
https://w3id.org/catenax/common/version
(mandatory as per CX-0002): version-string of the registered type of resource. For all endpoints related to the AAS-spec, this must be set to "3.0" as that's the current normative version of the AAS specification.
Digital Twin Registry as EDC Data Asset
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"cx-common": "https://w3id.org/catenax/ontology/common#",
"cx-taxo": "https://w3id.org/catenax/taxonomy#",
"dct": "http://purl.org/dc/terms/"
},
"@id": "{{ _.edcAssetId }}",
"properties": {
"dct:type": {
"@id": "cx-taxo:DigitalTwinRegistry"
},
"cx-common:version": "3.0"
},
"privateProperties": {
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "{{ _.url_backend }}",
"proxyQueryParams": "true",
"proxyPath": "true",
"proxyMethod": "false",
"oauth2:tokenUrl": "{{ _.url_keycl_backend }}",
"oauth2:clientId": "{{ _.client_id_backend }}",
"oauth2:clientSecretKey": "{{ _.sec_name_vault }}"
}
}
The property asset:prop:type
(deprecated and superseded by dct:type
- see CX-0002) denotes the type of Asset that
is registered. For all DTRs this property had be set to data.core.digitalTwinRegistry
. Providers may keep
this redundant property for backward compatibility purposes.
The HttpDataAddress above configures the following behavior:
baseUrl
: After successful negotiation, the data plane will delegate requests here and forward the answer. For the DTR, it's critical that the URL inserted here must end before the /shell-descriptors and /lookup segments.proxyPath
: This string can be either "true" or "false". If set to true, the EDC Data Plane will always forward the URL-segments added to the request to the dataplane to the backend URL. For example: IfbaseUrl="http://mydtr.com/api/v3"
andproxyPath="true"
then an authorized request tohttp://dataplane.com/shell-descriptors
will be delegated to the backendhttp://mydtr.com/api/v3/shell-descriptors
proxyQueryParams
: This string can be either "true" or "false". If set to true, the EDC Data Plane will always forward query parameters to the backend. For the /lookup APIs of the registry, this is critical.proxyMethod
: This string can be either "true" or "false". If "false", the Data Plane will change the HTTP-Verb to GET for all incoming requests. As there is no scenario in the Catena-X scope where a business partner manipulates data in a foreign DTR, it should be set to false.
If a Data Consumer wants to filter a Data Provider's catalog (assuming both use an EDC-based connector), the following
payload can be used against the EDC Management API's POST /catalog/request
endpoint:
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/"
},
"@type": "CatalogRequest",
"counterPartyAddress": "{{PROVIDER-DSP-ENDPOINT}}",
"protocol": "dataspace-protocol-http",
"querySpec": {
"offset": 0,
"limit": 50,
"filterExpression": [
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/"
},
"@type": "edc:Criterion",
"operandLeft": "'http://purl.org/dc/terms/type'.'@id'",
"operator": "=",
"operandRight": "https://w3id.org/catenax/taxonomy#DigitalTwinRegistry"
}
]
}
}
Submodel as EDC Data Asset
A Data Provider may create one Data Asset per Submodel or bundle them into one - yielding a smaller catalogue hence
better performance. The discovery-sequence does not strictly require uniformity here. Not even the typization via the
EDC-property dct:type
is functionally necessary. The discovery-sequence is still intact since a Data Consumer will
always know the Submodel's location relative to the Data Plane's baseUrl
from the submodel-descriptor's href
field.
The EDC-Asset shielding the Submodel is known from the descriptor's subprotocolBody
containing the Control-Plane-URL
and id of the EDC-Asset. For more details, see section Submodel Descriptor in the Digital Twin Registry.
The following shows an example for registration of a single AAS-Submodel as EDC Data Asset. The
properties
section is analogous to that of the DTR but additionally holds hasSemantics:semanticId
with the
hasSemantics
-prefix resolving to https://admin-shell.io/aas/3/0/HasSemantics/
. It is recommended and shall signify
the meaning of the Submodel's payload.
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"cx-common": "https://w3id.org/catenax/ontology/common#",
"cx-taxo": "https://w3id.org/catenax/taxonomy#",
"dct": "http://purl.org/dc/terms/",
"aas-semantics": "https://admin-shell.io/aas/3/0/HasSemantics/"
},
"@id": "{{ _.assetId }}",
"properties": {
"dct:type": {
"@id": "cx-taxo:Submodel"
},
"cx-common:version": "3.0",
"aas-semantics:semanticId": {
"@id": "urn:bamm:io.catenax.asset_tracker_links:1.0.0#AssetTrackerLinks"
}
},
"privateProperties": {
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "{{ _.url_backend }}",
"oauth2:tokenUrl": "{{ _.url_keycl_backend }}",
"oauth2:clientId": "{{ _.client_id_backend }}",
"oauth2:clientSecretKey": "{{ _.sec_name_vault }}",
"proxyQueryParams": "false",
"proxyPath": "true",
"proxyMethod": "false"
}
}
There is no normative guidance on how to register multiple Submodels bundled together yet. These bundles may include
all the Submodels of a specific semanticId, all Submodels of an asset or any other arbitrary quality. This may be added
to CX-0002 in future iterations. Even though the IDTA specifies a Submodel Repository API, in the context of the
Catena-X architecture it is not strictly necessary to adhere to it. Submodels will be found regardless,
given the URL-path relative to the baseUrl
is appended correctly to the Data Plane's URL in the href
field. The only
differences are the changed typization. proxyPath
parameter should be set "true"
either way.
{
"@context": {
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"cx-common": "https://w3id.org/catenax/ontology/common#",
"cx-taxo": "https://w3id.org/catenax/taxonomy#",
"dct": "http://purl.org/dc/terms/"
},
"@id": "{{ _.assetId }}",
"properties": {
"dct:type": {
"@id": "cx-taxo:SubmodelBundle"
},
"cx-common:version": "3.0"
},
"privateProperties": {
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "{{ _.url_backend }}",
"oauth2:tokenUrl": "{{ _.url_keycl_backend }}",
"oauth2:clientId": "{{ _.client_id_backend }}",
"oauth2:clientSecretKey": "{{ _.sec_name_vault }}",
"proxyQueryParams": "false",
"proxyPath": "true",
"proxyMethod": "false"
}
}
Usage Policies
For Digital Twin Registries, Data Providers are encouraged to only extend Data Offers that make no explicit checks to
use-case frameworks (formerly known as FrameworkAgreements
. The DTR is an Enablement Service that should only be
visible once to every Data Consumer in the DSP-Catalog because it is a meta-data broker for data from multiple
use-cases. Registering it with a Constraint that's specific to a particular use-case would restrict it only to a small
subset of the dataspace. Of course, the DTR could be registered once per use-case but that's not recommended as it
bloats the catalog and requires a lot of consumer-side processing. That's why Offers for a DTR should always
be extended to the dataspace using the at least two Constraints:
- Check for an active
Membership
credential. This is agnostic to use-cases but still ensures that a Consumer's VP is valid and issued by a common trust-anchor. - using the DTR as a roadsign in the discovery process is legitimate but requires a set of predefined behavior which
is why there's a
purpose
for the DTR.
Here's an example
{
"@context": [
"https://www.w3.org/ns/odrl.jsonld",
{
"cx-policy": "https://w3id.org/catenax/policy/"
}
],
"@type": "Policy",
"permission": [
{
"action": "use",
"constraint": {
"and": [
{
"leftOperand": "cx-policy:Membership",
"operator": "eq",
"rightOperand": "active"
},
{
"leftOperand": "cx-policy:UsagePurpose",
"operator": "eq",
"rightOperand": "cx.core.digitalTwinRegistry:1"
}
]
}
}
]
}
For Submodel-APIs, Data Providers must follow the guidelines from their use-case-standards which will usually require using the constraint checking for the associated use-case framework and the corresponding credentials.
Data Provisioning
Regulatory Compliance and Security
The services of this Kit will in many instances hold sensitive data. While sound access management is a prerequisite for every webservice, it is especially important in case of the DTR and Submodels. As they hold competitively sensitive data,unauthorized access is not only a data leak but a potential violation of regulatory compliance such as anti-trust law.
That's why there are a couple shared requirements that DTR-deployments must adhere to:
- If a Data Consumer has no legitimate interest, a AAS-descriptor must not be returned when requested.
- If a Data Consumer has a legitimate interest, a AAS-descriptor must not include any data (like
specificAssetIds
)of companies other than the involved Data Provider and Data Consumer. - If a Data Provider wants to share data publicly, a AAS-descriptor must only contain the
attributes
id
,submodelDescriptors
and thosespecificAssetIds
that were issued by the Data Provider and contain no hints of existing business relationships.
As the above properties are exposed not only via the AssetAdministrationShellRegistry interface but also the Discovery
interface (via the /lookup/shells
endpoint), it must not serve more data than specified above.
Versioning
Versioning in the Catena-X network is an essential task. This holds true for Digital Twins more specifically, too. The network builds on several specifications where changes in API or specifications could break existing communication channels. In a simple scenario (where the Data Provider offers access to a Submodel via DTR and a Data Consumer GETs both resources), these are the layers of complexity:
Versioned Object | Presence in the DT-Discovery Process | Description | Method to increment |
---|---|---|---|
Dataspace Protocol | 12, 22 | The body of the {{consumerControlPlane}}/v2/catalog/request -request includes a reference to a versioned endpoint of a business partner's DSP endpoint like {{providerControlPlane}}/api/v1/dsp | As the design of the EDC's /catalog/request -API is an implementation detail, Consumers must consistently monitor its versioning. As the EDC-Management-API abstracts the DSP-messages, changes in the DSP may reflect in the Management-API but will not always do so. If a Consumer application decides to interact with the dataspace without mediation of the EDC, this changes. |
AAS Specification | 4, 5, 15, 25 | For all AAS-related EDC-Assets (styled as dcat:Dataset in the catalog), a property cx-common:version must be added referring to the major and minor version of the AAS-spec. | For a major change in the AAS-spec, a new set of Catalog entries must be created by the Data Provider in accordance with the standards. For minor changes (AAS 3.x), Data Providers must signal the version in the https://w3id.org/catenax/common#version property of their contract offers and update it with each minor or patch update that's supported. Minor versions must also be signalled in the submodelDescriptor .ìnterface .protocol property. If the Submodel API increments with a major version, a new interface object must be added to the submodelDescriptor . |
Data Model Version | 5, 21, 29 | The structure of the Submodel is determined by the aspect-model's URN. It includes a section on versioning. | A new version of the semantic model requires either setup of a new Submodel (with a new Submodel ID and the new semantic ID) or update of an existing submodel-descriptor (with updated semantic ID). This includes updating registration information at the DTR. Rules on backward compatibility need to be considered. It may be requested to offer two Submodel versions at the same time. |
Here's a list of duties for Data Providers in case they integrate a new Submodel (or version of an existing one) to an existing twin:
- Expose a new Submodel to the Dataspace. If its URL is a subpath of one that's already registered as a EDC-Asset, there is no need to specifically register it as a new EDC-Asset and create a Contract Definition for it. However, if there is no such EDC-Asset, that's what a Data Provider must do: create an EDC-Asset, connect it to policies via the contract-definition-API and let consumers negotiate for it.
- If assetIds are known, the aasId can be discovered via
GET https://mydtr.com/api/v3/lookup/shells?assetIds=foo&assetIds=bar
. The query-parameters' values are base64url- encodedspecificAssetId
objects. If multiple shall be logically AND-chained, a Consumer must use the query- parameter-keyassetIds
multiple times. POST https://mydtr.com/api/v3/shell-descriptors/{{aasId}}/submodel-descriptors
with the (known or obtained) aasId in the path and the new submodel-descriptor in the body of the request. The attributesemanticId
is mandatory for submodel-descriptors in Catena-X. As defined in CX-0002, semanticIds in Catena-X are aspect-model-urns (see CX-0003) including a version.
Patterns for Submodel Deployment
Data Providers will usually follow one of two patterns:
- Digital Twin Repository: Deploying a dedicated Repository for the persistence of digital twin submodels and related data is the most convenient way to get started with the AAS. It bears the risk of data duplication and introduces the necessity for synchronization mechanisms while on the other hand reducing computational load on the authoring systems that the data originates from.
- Delegation: Wrapping an existing API with the AAS-Submodel API yields as a facade that is compliant to CX-0002. The wrapper delegates the incoming requests to the respective backend system. This is feasible in the Catena-X dataspace since offering data to the network requires mappings that are naturally dependent on the data's source format. More on data integration can be found in the corresponding CX e.V. guide. Equipping each Business Application with a Submodel-API-Wrapper will lead to a landscape of multiple Submodel-APIs that are linked by the DTR and visible in the Dataspace via a DSP-Connector.
Both approaches are architecturally valid. Data Consumers do not have to be aware about the deployment pattern employed by the Provider - the traversal and discovery algorithm will work either way.
Patterns for DTR Deployment
While it is generally possible to equip a Business Application not only with a Submodel- but also a DTR-facade, it is generally bad practice. There should only be a single DTR in a Provider's catalog. If there were multiple, a Consumer would have no way of knowing which DTR holds the relevant data, forcing him to iterate over all DTRs. This would exponentially increase the number of HTTP calls necessary to retrieve the relevant data.
Usually, a DTR will implement a persistence with the specified AAS-APIs for data ingestion specified in the SSP-001
profile of the AssetAdministrationShellRegistryService by means of POST endpoints, updatable with PUT and PATCH
requests (see reference implementation). These APIs should only be accessible by the Data Provider (for instance
by introduction of proper access control scopes or setting proxyMethod = false
, see registration). Delegation
as backend integration pattern is more inconvenient as the DTR must process and return reproducible IDs not only for
the assets but also for the AAS - this is hard to realize in a pure stateless implementation.
Notice
This work is licensed under the CC-BY-4.0.
- SPDX-License-Identifier: CC-BY-4.0
- SPDX-FileCopyrightText: 2023 Contributors of the Eclipse Foundation
- Source URL: https://github.com/eclipse-tractusx/tractusx-edc