Overview
In recent years, the importance of data sharing and distribution between organizations has been growing. However, simply exposing APIs makes it difficult to control "who" can access "which data" under "what conditions."
Dataspaces are a concept designed to solve this challenge. They provide a mechanism for data owners to maintain sovereignty while securely sharing data with trusted parties.
This article uses Eclipse EDC (Eclipse Dataspace Components), a dataspace implementation framework, to experience data exchange flows in a local environment.
Table of Contents
- What is a Dataspace?
- Overview of Eclipse EDC
- Environment Setup
- Executing the Data Exchange Flow
- Building a GUI Dashboard
- Summary
What is a Dataspace?
Challenges with Traditional Data Sharing
Traditional API integrations had the following challenges:
- Difficult access control: Once an API key is shared, any data can be retrieved
- Usage condition management: Conditions like "this data is for internal use only" cannot be technically enforced
- Auditing and tracking: It is difficult to track who retrieved data and when
The Dataspace Solution
Dataspaces solve these issues with the following approach:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Traditional API Integration โ
โ โ
โ Consumer โโโโโAPI Keyโโโโโ Provider API โ
โ โโโโโDataโโโโ โ
โ โ
โ Issue: Anyone can retrieve data, no condition management โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Dataspace โ
โ โ
โ 1. Consumer: "I want XX data" (catalog check) โ
โ 2. Provider: "I'll provide it if you meet these โ
โ conditions" (policy presentation) โ
โ 3. Both: Contract negotiation and agreement โ
โ 4. Consumer: Retrieve data based on the contract โ
โ โ
โ Benefits: Conditional access, auditable, sovereignty โ
โ maintained โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key Terminology
| Term | Description |
|---|---|
| Connector | Software for participating in a dataspace. Both Provider and Consumer have one |
| Provider | The party that provides data |
| Consumer | The party that retrieves data |
| Catalog | A listing of data published by the Provider |
| Policy | Conditions for data access (who, when, how it can be used) |
| Contract | An agreement between Provider and Consumer |
| EDR | Endpoint Data Reference. Temporary access information for data retrieval |
Overview of Eclipse EDC
Eclipse EDC is an open-source dataspace implementation framework developed by the Eclipse Foundation.
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ EDC Connector โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ Control Plane โ โ Data Plane โ โ
โ โ โ โ โ โ
โ โ - Catalog mgmt โ โ - Data transfer โ โ
โ โ - Contract โ โ - Proxy โ โ
โ โ negotiation โ โ - AuthN/AuthZ โ โ
โ โ - Policy eval โ โ โ โ
โ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Management API (REST) DSP Protocol (connector-to- โ
โ connector communication) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key API Endpoints
| Endpoint | Purpose |
|---|---|
/management/v3/assets | Asset (data) management |
/management/v3/policydefinitions | Policy management |
/management/v3/contractdefinitions | Contract definition management |
/management/v3/catalog/request | Catalog retrieval |
/management/v3/contractnegotiations | Contract negotiation |
/management/v3/transferprocesses | Data transfer |
/management/v3/edrs | EDR (access token) retrieval |
Environment Setup
Prerequisites
- Docker & Docker Compose
- Java 17 (for Gradle build)
- Python 3 (for proxy server)
1. Clone EDC Samples
git clone --depth 1 https://github.com/eclipse-edc/Samples.git edc-samples
cd edc-samples
2. Build the Connectors
# For Consumer (basic connector)
./gradlew transfer:transfer-00-prerequisites:connector:build
# For Provider (with DataPlane)
./gradlew transfer:transfer-03-consumer-pull:provider-proxy-data-plane:build
3. Create Docker Configuration Files
Dockerfile.consumer
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY transfer/transfer-00-prerequisites/connector/build/libs/connector.jar /app/connector.jar
ENTRYPOINT ["java", "-jar", "/app/connector.jar"]
Dockerfile.provider
FROM eclipse-temurin:17-jre
WORKDIR /app
COPY transfer/transfer-03-consumer-pull/provider-proxy-data-plane/build/libs/connector.jar /app/connector.jar
ENTRYPOINT ["java", "-jar", "/app/connector.jar"]
docker-compose.yml
services:
consumer:
build:
context: .
dockerfile: Dockerfile.consumer
container_name: edc-consumer
environment:
EDC_FS_CONFIG: /app/config/consumer.properties
volumes:
- ./config/consumer.properties:/app/config/consumer.properties:ro
ports:
- "29193:29193" # Management API
- "29194:29194" # DSP Protocol
provider:
build:
context: .
dockerfile: Dockerfile.provider
container_name: edc-provider
environment:
EDC_FS_CONFIG: /app/config/provider.properties
volumes:
- ./config/provider-dataplane.properties:/app/config/provider.properties:ro
ports:
- "19193:19193" # Management API
- "19194:19194" # DSP Protocol
- "19291:19291" # DataPlane Public API
4. Start the Connectors
docker compose up -d --build
Verify startup:
docker compose logs --tail 10
# Success if "Runtime ... ready" is displayed
Executing the Data Exchange Flow
Flow Overview
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ EDC Data Exchange Flow โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Step 1: Provider Preparation โ
โ โโโ Asset registration (what data to provide) โ
โ โโโ Policy definition (under what conditions) โ
โ โโโ Contract definition (linking assets and policies) โ
โ โ
โ Step 2: Catalog Retrieval โ
โ โโโ Consumer โ Provider: "What data do you have?" โ
โ โ
โ Step 3: Contract Negotiation โ
โ โโโ Consumer โ Provider: Agree on conditions, conclude contract โ
โ โ
โ Step 4: Data Transfer โ
โ โโโ Consumer: Initiate transfer based on contract โ
โ โ
โ Step 5: Data Retrieval โ
โ โโโ Consumer: Obtain EDR (access token) โ
โ โโโ Consumer โ Provider DataPlane: Retrieve data with token โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Step 1: Register Data on the Provider
Create an asset (define the data to be provided)
curl -X POST http://localhost:19193/management/v3/assets \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@id": "product-data",
"properties": {
"name": "Product Data",
"description": "Sample product information API"
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "https://jsonplaceholder.typicode.com/posts/1"
}
}'
Create a policy (define access conditions)
curl -X POST http://localhost:19193/management/v3/policydefinitions \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/", "odrl": "http://www.w3.org/ns/odrl/2/" },
"@id": "open-policy",
"policy": {
"@type": "odrl:Set",
"odrl:permission": [],
"odrl:prohibition": [],
"odrl:obligation": []
}
}'
Create a contract definition (link assets and policies)
curl -X POST http://localhost:19193/management/v3/contractdefinitions \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@id": "product-contract",
"accessPolicyId": "open-policy",
"contractPolicyId": "open-policy",
"assetsSelector": {
"@type": "CriterionDto",
"operandLeft": "https://w3id.org/edc/v0.0.1/ns/id",
"operator": "=",
"operandRight": "product-data"
}
}'
Step 2: Retrieve the Catalog
From the Consumer, check the data published by the Provider:
curl -X POST http://localhost:29193/management/v3/catalog/request \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@type": "CatalogRequest",
"counterPartyAddress": "http://provider:19194/protocol",
"protocol": "dataspace-protocol-http"
}'
The response contains the "Product Data" published by the Provider along with its Offer ID.
Step 3: Contract Negotiation
Use the Offer ID obtained from the catalog to initiate contract negotiation:
curl -X POST http://localhost:29193/management/v3/contractnegotiations \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/", "odrl": "http://www.w3.org/ns/odrl/2/" },
"@type": "ContractRequest",
"counterPartyAddress": "http://provider:19194/protocol",
"protocol": "dataspace-protocol-http",
"policy": {
"@id": "",
"@type": "odrl:Offer",
"odrl:permission": [],
"odrl:prohibition": [],
"odrl:obligation": [],
"odrl:target": { "@id": "product-data" },
"odrl:assigner": { "@id": "provider" }
}
}'
When negotiation is complete, the state becomes FINALIZED and a contractAgreementId is issued.
Step 4: Data Transfer
Once the contract is concluded, initiate data transfer:
curl -X POST http://localhost:29193/management/v3/transferprocesses \
-H "Content-Type: application/json" \
-d '{
"@context": { "edc": "https://w3id.org/edc/v0.0.1/ns/" },
"@type": "TransferRequest",
"connectorId": "provider",
"counterPartyAddress": "http://provider:19194/protocol",
"contractId": "",
"assetId": "product-data",
"protocol": "dataspace-protocol-http",
"transferType": "HttpData-PULL"
}'
Step 5: Retrieve Data
Once the transfer state becomes STARTED, obtain the EDR and retrieve the data:
# Obtain the EDR (access token)
curl http://localhost:29193/management/v3/edrs/Transfer ID>/dataaddress
# Retrieve the actual data
curl http://localhost:19291/public/ \
-H "Authorization: "
Response example:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident...",
"body": "quia et suscipit..."
}
Building a GUI Dashboard
While CLI operations are good for learning, a visual dashboard is more convenient for actual use. We built an EDC dashboard using Next.js + TypeScript.

Features
- Connector tab: Consumer/Provider asset, policy, and contract management
- Data Exchange Flow tab: Execute the full flow via GUI
- Contract Negotiation tab: View list and status of contract negotiations
- Data Transfer tab: View list and status of data transfers
Executing the Data Exchange Flow
In the "Data Exchange Flow" tab of the dashboard, data exchange can be executed in 5 steps.
Steps 1-2: Catalog Retrieval and Offer Selection

Clicking the "Retrieve Catalog" button displays the data published by the Provider (product data).
Steps 3-4: Contract Negotiation and Data Transfer

Once contract negotiation is complete, you can select the transfer type (HTTP Pull/Push) and start the data transfer.
Step 5: Data Retrieval Complete

When all steps are complete, the actual data retrieved from the Provider is displayed in JSON format.
Managing Contract Negotiations and Data Transfers
Contract Negotiation List

Data Transfer List

You can check the status of contract negotiations and data transfers in each tab.
Resolving CORS
Since accessing the EDC Management API directly from the browser causes CORS errors, we created a simple proxy server in Python:
# /api/consumer/* โ http://localhost:29193/management/*
# /api/provider/* โ http://localhost:19193/management/*
# /api/dataplane/* โ http://localhost:19291/public/*
Summary
What We Learned
- Dataspace concepts: Differences from traditional API integration, data sharing while maintaining sovereignty
- Eclipse EDC architecture: Control Plane / Data Plane, Management API
- Data exchange flow: Catalog retrieval -> Contract negotiation -> Data transfer -> Data retrieval
- Hands-on practice: Building EDC in a Docker environment, creating a GUI dashboard
Next Steps
- Leveraging policies: Setting policies with specific conditions (time limits, regional restrictions, etc.)
- Authentication and authorization: Vault integration and certificate management for production use
- Federated Catalog: Cross-provider catalog search
- Catena-X / GAIA-X: Integration with automotive industry and EU dataspace initiatives
References
The code used in this article was based on the GitHub repository.