ScalarDLによるデータ保証を検証

はじめに

前回のブログ記事では、分散型データベース管理システムであるScalarDB ClusterをAWSのEKS上で構築しました。

今回は、同じくScalar社の製品であるScalarDLを利用して、データの監査や非改ざん性の保証をどのように行うかを検証していきます。

データ保証の必要性

近年、企業や公共機関におけるセキュリティ事故が増加しており、データの改ざんや不正アクセスによる被害が深刻化しています。

特に、サイバー攻撃によるデータ漏洩や、内部不正による情報改ざんが頻発しており、企業はデータの真正性を保証する仕組みを強化する必要に迫られています。

弊社で取り組んでいるAI活用やRAG構築の場面においても、データの信頼性は極めて重要です。

RAGでは、外部データを取得してAIが回答を生成するため、取得元のデータが改ざんされていないことを保証する仕組みが求められます。

そのような時代背景の中で、企業や機関は、単なるデータ保護(暗号化やアクセス制御)だけでなく、改ざんを検出し、証跡を残す仕組みが求められています。

ScalarDLのような改ざん防止技術を組み合わせることで、AIが扱う情報の真正性を担保し、より安全な環境の中で正確な応答を生成することができます。

ScalarDLとは

ScalarDLは、データの完全性・非改ざん性・監査証跡の保証を目的としたScalar社にて提供しているシステムです。

ブロックチェーン技術を応用し、データトランザクションを暗号的に保護することで、信頼性の高いデータ管理を行うことができます。

以下の点がScalarDLの主な特徴です。

  • データの改ざん防止
    • ハッシュチェーン構造により、過去のデータが変更された場合に即座に検知可能。
  • 暗号署名による真正性の保証
  • 監査証跡(Audit Log)の記録
    • 取引履歴が改ざん不可能な形で保存され、監査や不正検知に活用可能。
  • 柔軟なデータベース連携
    • PostgreSQLやCassandraなどの一般的なデータベースと連携可能。

ScalarDLは、次の図に示すように、Ledger、Auditor、および Client SDKで構成されます。

それぞれの役割は以下のとおりです。

図 ScalarDLの構成([1]より引用)

ブロックチェーンとは

ScalarDLの理解を深めるために、ScalarDLで活用されているブロックチェーンという技術について簡単に説明します。

ブロックチェーンは、分散型ネットワーク上でデータを改ざんできない形で記録・管理する技術です。

従来の中央集権型データベースとは異なり、データが複数のノード(参加者)に分散され、すべての取引がチェーン状につながっています。

ブロックチェーンの仕組み

1. トランザクションの記録
複数の取引データが「ブロック」のかたまりとして生成される。

2. ハッシュによるデータの連鎖
各ブロックは前のブロックのハッシュ値を持ち、改ざんされるとその後のハッシュ値がすべて変わる。(=ハッシュチェーン)

3. 分散型ネットワークでの合意形成
複数のノードでデータの正当性を検証し、合意(コンセンサス)を形成する。

ブロックチェーンの特長

  • 改ざん耐性
    • ハッシュチェーンにより、データを変更するとすぐに検知される。
  • 分散管理
    • データが単一の管理者によらず分散されるため、シングルポイント障害が発生しにくい。
  • 透明性
    • 取引履歴が誰でも検証可能。

ScalarDLでは、上記ブロックチェーンにおける改ざん検知の仕組みを踏襲しつつ、以下の点で差異があります。

  • ブロックではなく取引単位でハッシュチェーンを実施。
  • ノード間でのコンセンサス形成を省略。

ブロックチェーンが仮想通貨などで活用されている技術であることは有名ですが、そもそもブロックで管理する必要がある理由は「不特定多数のノードで取引が発生する」ためです。

この仕組みのデメリットは、ブロック生成、およびノード間でのコンセンサス形成によるパフォーマンスの劣化です。

ScalarDLを導入する環境ではそもそも取引データが発生する対象は決まっており、複数ノードで発生する取引データをまとめたブロックで管理する必要がないことから、取引単位でのハッシュチェーンを用いることで、即時性が求められる処理においてもハッシュチェーンを用いたデータ真正性の担保を実現しております。

ScalarDLの強み

ScalarDLの強みは、耐改ざん性の高さと監査性の強化の他にも、導入する環境の柔軟性やコスト面での利点があります。
代表的なデータベース内蔵型 / 導入型の類似ソリューションとの比較を示します。

比較項目 ScalarDL Oracle Blockchain Table Guardtime KSI
改ざん防止
の手法
ハッシュチェーン+
デジタル署名
ブロックチェーン
テーブル
※DB内蔵型
ハッシュチェーン+
タイムスタンプ
※外部KSIノードで署名発行
制約 なし Oracle EE必須 外部KSIノード必須
性能 高速
※外部通信なしで完結
高速
※DBベース
低〜中
※外部KSIノードとの通信あり
外部監査 可能 不可
※DBアクセス権限必須
可能
導入費用 約200円/時
※PAYGライセンス
約736万円(1プロセッサ)
Oracle EEライセンス費
※サポート費用別
要問い合わせ
導入工数
学習コスト

Docker/K8s または
Javaの実装で導入

Oracle EEに内包
SQLの実装で導入可

SDK導入+KSI署名連携必須
署名/検証モデルの理解必須

導入事例・ユースケース

1. 金融取引のトランザクション履歴管理

金融取引では、銀行間の送金履歴を改ざんできない形で記録し、透明性を確保する必要があります。
ScalarDLの導入することで、銀行間送金の履歴を改ざん不可能な形で保存でき、監査機関がリアルタイムで取引データの整合性を検証できるため、透明性の確保や不正防止に繋がっております。

2. 医療機関における電子カルテの管理

医療機関では、医療訴訟時に備え、カルテの真正性を証明する必要があります。
ScalarDLの導入により、診療履歴の透明性が確保され、医療訴訟時の証拠として活用可能となります。
また、監査機関が独立した形でカルテの履歴を検証できるため、医療機関の信頼性向上に繋がります。

上記ケースの他にも、財務・税務文書の電子保存や、知的財産の使用権の主張のための証拠の管理など、客観的なデータの真正性が求められる様々な場面でScalarDLは活用されております。

検証

ここからは、公式のクイックスタートの手順を利用して実際にScalarDLを導入し、改ざん検知がどのように行われるかを確認していきます。
前提として、Docker、Docker Composeはインストールされているものとし、DBはMySQLを使用します。
※Docker・Docker Composeのインストールが未実施、または別のDBを使用したい場合は、こちらの手順をご参照ください。

導入するコンポーネント・流れ

ここからはScalarDLに関する用語が多数出てくるため、改めてここでScalarDLのコンポーネントと導入の流れを簡潔に説明をいたします。

「ScalarDLとは」でも説明の通り、ScalarDLではScalarDL Ledgerというコンポーネントにて署名付き・改ざん不可な形式でデータを管理しております。
ScalarDL Ledgerとクライアントのやりとりは、コントラクトと呼ばれるJavaのプログラムを介して、署名が付与されたAPIベースで行います。
APIに付与する署名はClient SDKにて生成され、監査・検知についてはScalarDL Auditorにて行います。

つまり、正確に真正性を保証するために必要なコンポーネントとしては

  • ScalarDL Ledger
  • Client SDK
  • ScalarDL Auditor

の3つとなります。

しかし、ScalarDLでは、ScalarDL AuditorがなくてもScalarDL Ledger単体で改ざんを検知できる仕組みが備わっております。
具体的な違いとして、ScalarDL Ledger単体では署名とデータ間での改ざん検知、ScalarDL Auditorも導入することで、署名の真正性も含めた改ざん検知を行っております。
つまり、ScalarDL Ledger単体では署名ごと改ざんされた場合の検証はできない形となりますが、改ざん検知の手順や結果として出力される内容がAuditorの有無で違いがないこと、公式のクイックスタートの手順ではAuditorが省略されていることから、今回はScalarDL Ledger単体で改ざん検知を行う構成で検証を行います。

手順の大まかな流れとしては

  1. ScalarDL (Ledger)を起動
  2. Client SDKをダウンロード
  3. コントラクトを作成
  4. 改ざん検知を検証

という順序で実施いたします。

1. ScalarDLを起動

1-1. ScalarDLサンプルリポジトリのクローン

コマンドプロンプトやターミナル等により任意の作業フォルダに移動後、次のコマンドを実行して、ScalarDLのサンプルリポジトリをクローンします。

git clone https://github.com/scalar-labs/scalardl-samples
cd scalardl-samples

1-2. ライセンス設定

クローンしたフォルダ内のdocker-compose-ledger-mysql.ymlファイルを以下のように変更し、Enterprise EditionのDockerイメージの有効化とライセンス設定を行います。

今回は試用版のライセンスを使用しているため、以下の部分を変更します。

include:
  - ./docker-compose-ledger-common.yml

services:scalardl-ledger:
    # 利用するイメージをBYOLのものに変更
    # image: ghcr.io/scalar-labs/scalardl-ledger:${SCALARDL_VERSION}
    image: ghcr.io/scalar-labs/scalardl-ledger-byol:${SCALARDL_VERSION}
    〜
    environment: # ライセンスキーを設定
      ##### PLEASE REPLACE THIS VALUE WITH YOUR LICENSE KEY #####
      - SCALAR_DL_LICENSING_LICENSE_KEY=[試用版のライセンスキー]
      ##### PLEASE REPLACE THIS VALUE WITH YOUR LICENSE KEY #####

1-3. MySQLを起動

以下のコマンドを実行して、MySQLを起動します。

docker compose -f docker-compose-ledger-mysql.yml up -d

1-4. データベーススキーマのロード

次のコマンドを実行して、ScalarDL Ledger のデータベーススキーマをロードします。

docker compose -f docker-compose-ledger-mysql.yml up -d scalardl-ledger-schema-loader

1-5. ScalarDL Ledgerを起動

次のコマンドを実行して、ScalarDL Ledgerを起動します。

docker compose -f docker-compose-ledger-mysql.yml up -d

2. Client SDKをダウンロード

2-1. バージョン指定

次のコマンドを実行して、デプロイされたScalarDLバージョンと同じバージョンをダウンロードの対象として指定します。

VERSION=$(grep SCALARDL_VERSION .env | awk -F= '{print $2}')

2-2. ダウンロード

次のコマンドを実行して、リポジトリをクローン後にClient SDKをダウンロードします。

git clone https://github.com/scalar-labs/scalardl-java-client-sdk.git
cd scalardl-java-client-sdk
git checkout v$VERSION
curl -OL https://github.com/scalar-labs/scalardl-java-client-sdk/releases/download/v$VERSION/scalardl-java-client-sdk-$VERSION.zip
unzip scalardl-java-client-sdk-$VERSION.zip
mv scalardl-java-client-sdk-$VERSION client

3. プロパティ設定

client.propertiesとしてScalarDLクライアントのプロパティを定義し、ScalarDL Ledgerとやり取りをする環境を整えます。
以下のコマンドを実行することで、必要最低限なプロパティを含む設定ファイル(client.properties)を作成します。

cat < 'EOF' > client.properties
# A host name for ScalarDL Ledger.
scalar.dl.client.server.host=localhost

# An ID for the certificate holder. This must be configured for each private key and must be unique in the system.
scalar.dl.client.cert_holder_id=foo

# A path to the certificate file.
scalar.dl.client.cert_path=../fixture/client.pem

# A path to the private key file.
scalar.dl.client.private_key_path=../fixture/client-key.pem
EOF

4. 証明書を登録

以下のコマンドを実行し、証明書を ScalarDL Ledger に登録できます。

client/bin/scalardl register-cert --properties client.properties

5. コントラクトを作成

コントラクトはScalarDL LedgerのAPIを呼び出すJavaクラスです。
以下は、サンプルのコントラクトとなるStateUpdater.javaの内容です。
定義済みの基本コントラクトクラス (JacksonBasedContract クラスなど) を拡張し、invoke メソッドをオーバーライドしてビジネスロジックを実装しています。

具体的には、引数からクライアント定義のアセット ID (asset_id) と状態 (state) を抽出し、指定された状態がアセットの現在の状態と異なる場合は、アセット ID を台帳内の状態に関連付けます。

package com.org1.contract;

import com.fasterxml.jackson.databind.JsonNode;
import com.scalar.dl.ledger.contract.JacksonBasedContract;
import com.scalar.dl.ledger.exception.ContractContextException;
import com.scalar.dl.ledger.statemachine.Asset;
import com.scalar.dl.ledger.statemachine.Ledger;
import java.util.Optional;
import javax.annotation.Nullable;

public class StateUpdater extends JacksonBasedContract {

  @Nullable
  @Override
  public JsonNode invoke(Ledger<JsonNode> ledger, JsonNode argument, @Nullable JsonNode properties) {
    if (!argument.has("asset_id") || !argument.has("state")) {
      // ContractContextException is the only throwable exception in a contract and
      // it should be thrown when a contract faces some non-recoverable error
      throw new ContractContextException("please set asset_id and state in the argument");
    }

    // 引数で受け取るアセットIDで対象のデータを指定
    String assetId = argument.get("asset_id").asText();

    // アセットIDで該当するレコードのstateを更新対象として指定
    int state = argument.get("state").asInt();

    Optional<Asset<JsonNode>> asset = ledger.get(assetId);

    if (!asset.isPresent() || asset.get().data().get("state").asInt() != state) {
      ledger.put(assetId, getObjectMapper().createObjectNode().put("state", state));
    }

    return null;
  }
}

6. コントラクトを登録

以下のコマンドを実行してコントラクトを登録します。

client/bin/scalardl register-contract --properties client.properties --contract-id StateUpdater --contract-binary-name com.org1.contract.StateUpdater --contract-class-file build/classes/java/main/com/org1/contract/StateUpdater.class

7. コントラクトを実行

コントラクトを実行してデータを更新します。
コントラクトの実装の通り、asset_idを指定し、更新するstateの値を指定します。
ScalarDLではこのようにコントラクトを通じてデータを更新することで改ざんと扱われずにデータを更新することができます。

client/bin/scalardl execute-contract --properties client.properties --contract-id StateUpdater --contract-argument '{"asset_id":"some_asset", "state":3}'

8. Ledger の状態を検証

次のコマンドを実行すると、Ledger の状態を検証できます。

client/bin/scalardl validate-ledger --properties client.properties --asset-id="some_asset"

手順7の結果として、データが改ざんされていないことを示す以下の内容が出力されます。

{
  "result": "Valid",
  "message": "The data is consistent."
}

9. データ改ざん試行

チュートリアルにはありませんが、データが改ざんされた場合にどのような結果となるのかについても確認します。
以下のコマンドでコントラクトを介さずに直接データを更新してください。

docker exec -it mysql mysql -u root -p
USE scalardb;
UPDATE ledgers SET state="999" WHERE asset_id="some_asset";

この状態で手順8と同様にLedger の状態を検証します。

client/bin/scalardl validate-ledger --properties client.properties --asset-id="some_asset"

以下の通り、改ざんを検知したことが結果として出力されます。

{
  "result": "Signature verification failed",
  "message": "Data inconsistency detected!"
}

最後に

今回は、データの真正性を保証し、改ざん検知を行うことができるScalarDLの導入を行いました。
改ざんの検証はコマンドにて実行できるため、定期実行による改ざん検知の自動化や、踏み台サーバなど経由した外部からの検証も可能となります。

導入に際しても、Dockerイメージを取得した後にいくつかの設定をするのみで導入可能であることは大きな利点かと思います。
別途サーバを用意する必要もないため、アーキテクチャの柔軟性とコストの削減を両立することができます。

セキュリティを担保した柔軟なAI利活用を目指す弊社では、今後のScalarDLの発展に注視していきます。

ridge-i.com

引用文献

[1] ScalarDL Implementation, 閲覧日時:2025年3月17日
https://scalardl.scalar-labs.com/docs/3.8/implementation

参考記事

ScalarDL Overview, 閲覧日時:2025年3月16日
https://scalardl.scalar-labs.com/docs/3.8/overview

ScalarDL Implementation, 閲覧日時:2025年3月16日
https://scalardl.scalar-labs.com/docs/3.8/implementation

Get Started with ScalarDL Ledger, 閲覧日時:2025年3月17日
https://scalardl.scalar-labs.com/docs/latest/getting-started