はじめに
近年、企業間でのデータ共有・流通の重要性が高まっています。しかし、単純にAPIを公開するだけでは、「誰が」「どんな条件で」「どのデータに」アクセスできるかを制御することが困難です。
データスペース(Dataspace) は、この課題を解決するための概念です。データの所有者が主権を持ちながら、信頼できる相手とデータを安全に共有できる仕組みを提供します。
本記事では、データスペースの実装基盤である Eclipse EDC(Eclipse Dataspace Components) を使って、ローカル環境でデータ交換フローを体験します。
目次
- データスペースとは?
- Eclipse EDCの概要
- 環境構築
- データ交換フローの実行
- GUIダッシュボードの作成
- まとめ
データスペースとは?
従来のデータ共有の課題
従来のAPI連携では、以下のような課題がありました:
- アクセス制御が困難 : APIキーを渡すと、どんなデータでも取得できてしまう
- 利用条件の管理 : 「このデータは社内利用のみ」といった条件を技術的に強制できない
- 監査・追跡 : 誰がいつデータを取得したか追跡しづらい
データスペースの解決策
データスペースは以下の仕組みで解決します:
┌─────────────────────────────────────────────────────────────┐
│ 従来のAPI連携 │
│ │
│ Consumer ─────APIキー────→ Provider API │
│ ←────データ──── │
│ │
│ 課題: 誰でもデータ取得可能、条件管理なし │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ データスペース │
│ │
│ 1. Consumer: 「〇〇のデータが欲しい」(カタログ確認) │
│ 2. Provider: 「この条件を満たせば提供する」(ポリシー提示) │
│ 3. 両者: 契約交渉・合意 │
│ 4. Consumer: 契約に基づきデータ取得 │
│ │
│ メリット: 条件付きアクセス、監査可能、主権維持 │
└─────────────────────────────────────────────────────────────┘
主要な用語
| 用語 | 説明 |
|---|---|
| Connector | データスペースに参加するためのソフトウェア。ProviderとConsumerそれぞれが持つ |
| Provider | データを提供する側 |
| Consumer | データを取得する側 |
| Catalog | Providerが公開しているデータの一覧 |
| Policy | データアクセスの条件(誰が、いつ、どのように使えるか) |
| Contract | ProviderとConsumer間で結ばれる契約 |
| EDR | Endpoint Data Reference。データ取得用の一時的なアクセス情報 |
Eclipse EDCの概要
Eclipse EDC は、Eclipse Foundationが開発するオープンソースのデータスペース実装基盤です。
アーキテクチャ
┌─────────────────────────────────────────────────────────────┐
│ EDC Connector │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Control Plane │ │ Data Plane │ │
│ │ │ │ │ │
│ │ - カタログ管理 │ │ - データ転送 │ │
│ │ - 契約交渉 │ │ - プロキシ │ │
│ │ - ポリシー評価 │ │ - 認証・認可 │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ Management API (REST) DSP Protocol (コネクタ間通信) │
└─────────────────────────────────────────────────────────────┘
主要なAPIエンドポイント
| エンドポイント | 用途 |
|---|---|
/management/v3/assets | アセット(データ)の管理 |
/management/v3/policydefinitions | ポリシーの管理 |
/management/v3/contractdefinitions | コントラクト定義の管理 |
/management/v3/catalog/request | カタログの取得 |
/management/v3/contractnegotiations | 契約交渉 |
/management/v3/transferprocesses | データ転送 |
/management/v3/edrs | EDR(アクセストークン)の取得 |
環境構築
前提条件
- Docker & Docker Compose
- Java 17(Gradleビルド用)
- Python 3(プロキシサーバー用)
1. EDC Samplesのクローン
git clone --depth 1 https://github.com/eclipse-edc/Samples.git edc-samples
cd edc-samples
2. コネクタのビルド
# Consumer用(基本コネクタ)
./gradlew transfer:transfer-00-prerequisites:connector:build
# Provider用(DataPlane付き)
./gradlew transfer:transfer-03-consumer-pull:provider-proxy-data-plane:build
3. Docker設定ファイルの作成
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. コネクタの起動
docker compose up -d --build
起動確認:
docker compose logs --tail 10
# "Runtime ... ready" と表示されれば成功
データ交換フローの実行
フロー全体像
┌────────────────────────────────────────────────────────────────────┐
│ EDCデータ交換フロー │
├────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Provider準備 │
│ ├── アセット登録(どんなデータを提供するか) │
│ ├── ポリシー定義(どんな条件で提供するか) │
│ └── コントラクト定義(アセットとポリシーの紐付け) │
│ │
│ Step 2: カタログ取得 │
│ └── Consumer → Provider: 「何のデータがありますか?」 │
│ │
│ Step 3: 契約交渉 │
│ └── Consumer ↔ Provider: 条件に合意し契約締結 │
│ │
│ Step 4: データ転送 │
│ └── Consumer: 契約に基づきTransfer開始 │
│ │
│ Step 5: データ取得 │
│ ├── Consumer: EDR(アクセストークン)取得 │
│ └── Consumer → Provider DataPlane: トークンでデータ取得 │
│ │
└────────────────────────────────────────────────────────────────────┘
Step 1: Providerにデータを登録
アセット作成 (提供するデータの定義)
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": "製品データ",
"description": "サンプル製品情報API"
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "https://jsonplaceholder.typicode.com/posts/1"
}
}'
ポリシー作成 (アクセス条件の定義)
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": []
}
}'
コントラクト定義作成 (アセットとポリシーの紐付け)
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: カタログ取得
Consumerから、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"
}'
レスポンスには、Providerが公開している「製品データ」とそのOffer IDが含まれます。
Step 3: 契約交渉
カタログから取得したOffer IDを使って契約交渉を開始します:
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" }
}
}'
交渉が完了すると、状態が FINALIZED になり、contractAgreementId が発行されます。
Step 4: データ転送
契約が締結されたら、データ転送を開始します:
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: データ取得
Transfer状態が STARTED になったら、EDRを取得してデータを取得します:
# EDR(アクセストークン)の取得
curl http://localhost:29193/management/v3/edrs/Transfer ID>/dataaddress
# 実際のデータ取得
curl http://localhost:19291/public/ \
-H "Authorization: "
レスポンス例:
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident...",
"body": "quia et suscipit..."
}
GUIダッシュボードの作成
CLIでの操作は学習には良いですが、実際の運用では視覚的なダッシュボードが便利です。
今回、Next.js + TypeScriptでEDCダッシュボードを作成しました。

機能
- コネクタタブ : Consumer/Providerのアセット・ポリシー・コントラクト管理
- データ交換フロータブ : GUIでフルフロー実行
- 契約交渉タブ : 契約交渉の一覧・状態確認
- データ転送タブ : データ転送の一覧・状態確認
データ交換フローの実行
ダッシュボードの「データ交換フロー」タブでは、5つのステップでデータ交換を実行できます。
Step 1-2: カタログ取得とオファー選択

「カタログ取得」ボタンをクリックすると、Providerが公開しているデータ(製品データ)が表示されます。
Step 3-4: 契約交渉とデータ転送

契約交渉が完了すると、転送タイプ(HTTP Pull/Push)を選択してデータ転送を開始できます。
Step 5: データ取得完了

全てのステップが完了すると、Providerから取得した実際のデータがJSON形式で表示されます。
契約交渉・データ転送の管理
契約交渉一覧

データ転送一覧

各タブで契約交渉やデータ転送の状態を確認できます。
CORSの解決
ブラウザからEDC Management APIに直接アクセスするとCORSエラーが発生するため、
Pythonで簡易プロキシサーバーを作成しました:
# /api/consumer/* → http://localhost:29193/management/*
# /api/provider/* → http://localhost:19193/management/*
# /api/dataplane/* → http://localhost:19291/public/*
まとめ
今回学んだこと
- データスペースの概念 : 従来のAPI連携との違い、主権を維持したデータ共有
- Eclipse EDCの構成 : Control Plane / Data Plane、Management API
- データ交換フロー : カタログ取得 → 契約交渉 → データ転送 → データ取得
- 実践 : Docker環境でのEDC構築、GUIダッシュボードの作成
次のステップ
- ポリシーの活用 : 特定の条件(時間制限、地域制限など)を持つポリシーの設定
- 認証・認可 : 実運用向けのVault統合、証明書管理
- Federated Catalog : 複数のProviderを横断したカタログ検索
- Catena-X / GAIA-X : 自動車業界やEUのデータスペースイニシアチブとの連携
参考リンク
この記事で使用したコードはGitHub をベースに作成しました。