はじめに

近年、企業間でのデータ共有・流通の重要性が高まっています。しかし、単純にAPIを公開するだけでは、「誰が」「どんな条件で」「どのデータに」アクセスできるかを制御することが困難です。

データスペース(Dataspace) は、この課題を解決するための概念です。データの所有者が主権を持ちながら、信頼できる相手とデータを安全に共有できる仕組みを提供します。

本記事では、データスペースの実装基盤である Eclipse EDC(Eclipse Dataspace Components) を使って、ローカル環境でデータ交換フローを体験します。

目次

  1. データスペースとは?
  2. Eclipse EDCの概要
  3. 環境構築
  4. データ交換フローの実行
  5. GUIダッシュボードの作成
  6. まとめ

データスペースとは?

従来のデータ共有の課題

従来のAPI連携では、以下のような課題がありました:

  • アクセス制御が困難 : APIキーを渡すと、どんなデータでも取得できてしまう
  • 利用条件の管理 : 「このデータは社内利用のみ」といった条件を技術的に強制できない
  • 監査・追跡 : 誰がいつデータを取得したか追跡しづらい

データスペースの解決策

データスペースは以下の仕組みで解決します:

┌─────────────────────────────────────────────────────────────┐
│  従来のAPI連携                                               │
│                                                             │
│  Consumer ─────APIキー────→ Provider API                    │
│            ←────データ────                                   │
│                                                             │
│  課題: 誰でもデータ取得可能、条件管理なし                      │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│  データスペース                                              │
│                                                             │
│  1. Consumer: 「〇〇のデータが欲しい」(カタログ確認)         │
│  2. Provider: 「この条件を満たせば提供する」(ポリシー提示)    │
│  3. 両者: 契約交渉・合意                                     │
│  4. Consumer: 契約に基づきデータ取得                         │
│                                                             │
│  メリット: 条件付きアクセス、監査可能、主権維持                │
└─────────────────────────────────────────────────────────────┘

主要な用語

用語説明
Connectorデータスペースに参加するためのソフトウェア。ProviderとConsumerそれぞれが持つ
Providerデータを提供する側
Consumerデータを取得する側
CatalogProviderが公開しているデータの一覧
Policyデータアクセスの条件(誰が、いつ、どのように使えるか)
ContractProviderとConsumer間で結ばれる契約
EDREndpoint 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/edrsEDR(アクセストークン)の取得

環境構築

前提条件

  • 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ダッシュボードを作成しました。

EDC Connector Dashboard - コネクタ一覧

機能

  1. コネクタタブ : Consumer/Providerのアセット・ポリシー・コントラクト管理
  2. データ交換フロータブ : GUIでフルフロー実行
  3. 契約交渉タブ : 契約交渉の一覧・状態確認
  4. データ転送タブ : データ転送の一覧・状態確認

データ交換フローの実行

ダッシュボードの「データ交換フロー」タブでは、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/*

まとめ

今回学んだこと

  1. データスペースの概念 : 従来のAPI連携との違い、主権を維持したデータ共有
  2. Eclipse EDCの構成 : Control Plane / Data Plane、Management API
  3. データ交換フロー : カタログ取得 → 契約交渉 → データ転送 → データ取得
  4. 実践 : Docker環境でのEDC構築、GUIダッシュボードの作成

次のステップ

  • ポリシーの活用 : 特定の条件(時間制限、地域制限など)を持つポリシーの設定
  • 認証・認可 : 実運用向けのVault統合、証明書管理
  • Federated Catalog : 複数のProviderを横断したカタログ検索
  • Catena-X / GAIA-X : 自動車業界やEUのデータスペースイニシアチブとの連携

参考リンク


この記事で使用したコードはGitHub をベースに作成しました。