Web Resource Ledger について
Web Resource Ledger(WRL)はセルフホスト可能なウェブ証拠記録サービスで、スクリーンショット、レンダリング済みHTML、HTTPヘッダー、署名付きWACZを保存します。共有可能な検証ページとオフラインCLIで、記録の完全性を確認できます。
主な機能
- 01スクリーンショット、HTML、応答ヘッダーを取得
- 02Ed25519署名付きWACZを作成
- 03共有可能な検証ページを提供
- 04取得プロセスの証明PDFを発行
- 05オフライン検証CLIを提供
活用シーン
- 01特定時点のウェブコンテンツを証拠として保存
- 02取得したページを共有して第三者が検証
- 03CLIでWACZアーカイブをオフライン検証
MCP 対応
WRLは取得、取得記録の参照、一覧表示、検証の4操作をMCPツールとして互換性のあるエージェントやIDEに公開します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://api.webresourceledger.com/mcpclaude mcp add --transport http benpeter-web-resource-ledger https://api.webresourceledger.com/mcp{"mcpServers":{"benpeter-web-resource-ledger":{"type":"http","url":"https://api.webresourceledger.com/mcp"}}}Cursor で開く{"servers":{"benpeter-web-resource-ledger":{"type":"http","url":"https://api.webresourceledger.com/mcp"}}}VS Code で開く{"mcpServers":{"benpeter-web-resource-ledger":{"type":"http","url":"https://api.webresourceledger.com/mcp"}}}{"mcpServers":{"benpeter-web-resource-ledger":{"serverUrl":"https://api.webresourceledger.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://api.webresourceledger.com/mcp認証が必要ツール
詳細
Web Resource Ledger(WRL)
ウェブコンテンツの暗号学的証拠――ページの表示内容を記録し、記録日時を示し、誰でも検証できる証拠を提供します。
URLを送信すると、スクリーンショット、レンダリング済みHTML、HTTPヘッダー、Ed25519署名付きWACZバンドルが返されます。検証URLはアカウントなしで誰でも利用できます。独自のインフラにデプロイすれば、記録データも鍵も証拠も自分で管理できます。
WRLは、作業を人間が指示し、ほぼすべてをLLM(Claude)が構築しました。MVPから本番環境まで、各フェーズの記録をdocs/evolution/で公開しています。プロンプト、エージェント間の議論、決定事項、成果はすべて公開されています。
認証、検証、バッチ記録、MCP連携に関する包括的なガイドについては、docs.webresourceledger.comをご覧ください。
ステータス: 単一オペレーターによる本番サービスのデプロイです。ロードマップの3つのアクトはすべて完了しています。APIは1.0以前ですが、機能しており、デプロイ済みで、実際のトラフィックに対応しています。
利用できる機能
APIを1回呼び出すだけで、次の情報を取得できます。
- 2種類のスクリーンショット(PNG)――Cookie同意の解除前と解除後を記録し、バナーの有無と背後のページコンテンツの両方を保持します
- レンダリング済みHTML――JavaScriptの実行後のDOMです
- HTTPレスポンスヘッダー――記録時点におけるサーバーのレスポンスです
- 署名付きWACZバンドル――すべての成果物をまとめ、ハッシュ化し、Ed25519で署名します
- 検証URL――誰でも信頼性を確認できる共有可能なリンクです
- FRE 902(13)認証PDF――
GET /v1/captures/{captureId}/certificateは、記録プロセスと完全性を示す証拠を記載した署名付きPDFを返します。Rule 902(13)に基づく自己認証の根拠として利用できるよう設計されています
コンテンツセキュリティ
WRLは、記録を開始する前に、送信されたすべてのURLを脅威インテリジェンスデータベースと照合します。
- 脅威(マルウェア、フィッシングなど)として特定されたURLは、送信時に422レスポンスで拒否されます。
- 既存の記録は毎日再スキャンされます。再スクリーニングに失敗した記録は隔離され、メタデータには引き続きアクセスできますが、成果物のダウンロードには451が返されます。
- スクリーニングは、サービスを利用できない場合も適切に機能を縮退します。脅威インテリジェンスサービスが利用できない場合、記録は通常どおり続行されます。記録レコードの
threatCheckフィールドに、結果としてpass、fail、unavailableのいずれかが設定されます。
環境変数のGOOGLE_WEB_RISK_API_KEYでサービスを設定してください(下記のステップ8bを参照)。このキーは省略可能です。省略するとスクリーニングは無効になり、すべての記録でthreatCheck: unavailableが報告されます。
使用方法
WRLの実行中のインスタンスが必要です。下記のセットアップを参照してください。
export WRL_API_KEY=your_tenant_api_key
テナントキーは管理者APIから作成します(ステップ8aを参照)。従来の静的キーを使用するデプロイでは、WRL_API_KEYはCAPTURE_API_KEYの値です。
以下の例ではapi.webresourceledger.comを使用しています。ローカル開発ではlocalhost:8787に置き換えてください。セルフホストの場合は、独自のデプロイURLに置き換えます。
ステップ1:記録を送信する
curl -X POST https://api.webresourceledger.com/v1/captures \
-H "Authorization: Bearer $WRL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
{
"id": "cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"statusUrl": "https://api.webresourceledger.com/v1/captures/cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6/status",
"note": "Use GET /v1/captures to list and search your captures."
}
記録にはいつでもアクセスできます。GET /v1/capturesを使って一覧表示するか、記録IDを保存して直接アクセスしてください。
ステップ2:完了をポーリングする
curl https://api.webresourceledger.com/v1/captures/cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6/status
statusがcompleteまたはfailedになるまでポーリングします。完了すると、レスポンスにcaptureUrlが含まれます。
ステップ3:成果物を取得する
curl https://api.webresourceledger.com/v1/captures/cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
メタデータと署名付き成果物URL(screenshot、html、headers、wacz)、およびverifyUrlが返されます。
Step 4: バンドルを検証する
curl https://api.webresourceledger.com/v1/verify/cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
最大4つのチェック結果(artifactHashes、bundleHash、signature、新しいキャプチャの場合はtimestamp)を含むJSON形式の検証結果を返します。タイムスタンプのチェックでは、キャプチャ時に取得したRFC 3161準拠の独立したタイムスタンプを検証します。レガシーキャプチャの場合、チェック結果は3つです。ステップ3のverifyUrlは、ブラウザーで人間が読みやすいページとしても表示されます。
キャプチャURLはそのまま共有できます。キャプチャIDがあれば誰でもキャプチャとそのアーティファクトにアクセスできます。トークンは不要です。
共有: キャプチャURLはそのまま共有できます。URLがあれば誰でもキャプチャレコードとすべてのアーティファクトにアクセスできます。真正性の証明には、人間が読みやすい検証ページを表示する
verifyUrlを共有してください。
オフライン検証
CMS/PKCS#7証明書チェーン全体の検証など、独立したオフライン検証には、CLIツールを使用してください。
npx @w-r-l/verify capture.wacz --origin https://api.webresourceledger.com
詳細はpackages/verify/をご覧ください。
キャプチャを検索する
GET /v1/capturesはキャプチャの一覧を返します(APIキーが必要です)。キャプチャIDの確認や復元に使用してください。
curl https://api.webresourceledger.com/v1/captures \
-H "Authorization: Bearer $WRL_API_KEY"
{
"data": [
{
"id": "cap_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"status": "complete",
"url": "https://example.com",
"createdAt": "2024-01-15T10:30:00.000Z",
"completedAt": "2024-01-15T10:30:45.123Z"
}
],
"pagination": {
"cursor": null,
"hasMore": false,
"limit": 20
}
}
任意のクエリパラメーター:limit(1~100、既定値は20)、cursor(ページング用)、status(pending、complete、failed、quarantinedのいずれか)。
キャプチャのリクエスト数はIPあたり1分間に10件までに制限されます。検証はIPあたり1分間に60件までに制限されます。エラーレスポンスにはRFC 9457のapplication/problem+json形式を使用します。詳細はopenapi.yamlをご覧ください。
詳細ガイド:一連の手順についてははじめにをご覧ください。また、すべてのエンドポイント一覧についてはAPIリファレンスをご覧ください。
セットアップ
前提条件
- Wrangler CLIをインストールし、認証済みであること
- Node.js 22+(
.nvmrcを参照) - R2とBrowser Renderingが有効になっているCloudflareアカウント
1. 依存関係をインストールする
npm install
2. D1データベースを作成する
wrangler d1 create wrl-metadata
返されたIDをwrangler.tomlの[[d1_databases]]にあるdatabase_idに設定します。その後、マイグレーションを適用します。
wrangler d1 migrations apply wrl-metadata
2a. KVネームスペースを作成する(レート制限用)
KVはレート制限カウンターにのみ使用します。ネームスペースを作成します。
wrangler kv namespace create wrl-kv
返されたidとpreview_idをwrangler.tomlに設定します。
3. R2バケットを作成する
wrangler r2 bucket create wrl-captures
wrangler r2 bucket create wrl-captures-preview
4. キャプチャAPIキーを設定する(レガシー用フォールバック)
CAPTURE_API_KEYは静的なベアラートークンで、D1にテナントキーが見つからない場合のフォールバックとして機能します。新規デプロイでは、管理API(ステップ8a)をセットアップし、代わりにテナントキーを作成することを検討してください。既存のデプロイでは、移行中もこのキーを引き続き使用できます。
上記の使用例では、これは$WRL_API_KEYです。
キーを生成します。
openssl rand -hex 32
本番環境のシークレットを設定します。
wrangler secret put CAPTURE_API_KEY
ローカル開発環境では、.dev.varsに追加します。
CAPTURE_API_KEY=<hex string from the command above>
セキュリティ: この値をバージョン管理にコミットしないでください。.dev.varsはすでに.gitignoreに含まれています。
5. 署名キーを設定する
WRLはEd25519を使用してWACZバンドルに署名します。署名キーは任意です。SIGNING_KEYが設定されていない場合、キャプチャは正常に完了しますが、WACZバンドルは作成されません(スクリーンショット、HTML、ヘッダーは引き続き保存されます)。
キーペアを生成します。
node scripts/generate-signing-key.js
スクリプトは秘密鍵(PKCS8 DER、base64)と、それに対応する公開鍵(raw、base64)を出力します。検証用の公開鍵は、署名された各バンドルに自動的に埋め込まれるため、別途配布する必要はありません。
本番環境のシークレットを設定します。
wrangler secret put SIGNING_KEY
# Paste the private key (PKCS8 DER, base64) when prompted
ローカル開発環境では、.dev.varsに追加します。
SIGNING_KEY=<base64 string from the script>
セキュリティ: 秘密鍵をバージョン管理にコミットしないでください。.dev.varsはすでに.gitignoreに含まれています。
6. IPハッシュシードを設定する(推奨)
IP_HASH_SEEDは、IPアドレスがログに記録される前にハッシュ化するために使用するHMACシードです。設定しない場合、ログエントリーにIPアドレスの相関情報が記録されないため、不正利用の分析ができません。
シードを生成します。
openssl rand -hex 32
本番環境のシークレットを設定します。
wrangler secret put IP_HASH_SEED
ローカル開発環境では、.dev.varsに追加します。
IP_HASH_SEED=<hex string from the command above>
7. Coralogix のログ取り込みを設定する(本番環境でのオブザーバビリティに必要)
CORALOGIX_SEND_KEY は、構造化ログを Coralogix に取り込むための API キーです。このキーがなくても Worker は通常どおり動作しますが、ログはコンソールにのみ出力され、構造化ログの取り込みは行われません。Coralogix を使用しないフォーク開発者にとって、このキーは実質的に任意です。
Coralogix ダッシュボードの Settings > Send Your Data > API Keys で送信キーを確認してください。
本番環境のシークレットを設定します。
wrangler secret put CORALOGIX_SEND_KEY
ローカル開発では、構造化ログはコンソールに出力されます。wrangler dev ではキーは必要ありません。
8. CORS オリジンを設定する(任意)
CORS_ORIGINS は、CORS プリフライトレスポンスで許可するオリジンをカンマ区切りで指定するリストです。ブラウザーベースのクライアントから API を直接呼び出す場合にのみ必要です。
環境変数として wrangler.toml に設定します(シークレットではありません)。
[vars]
CORS_ORIGINS = "https://app.example.com,https://www.example.com"
省略すると、ブラウザーからのクロスオリジンリクエストはブロックされます。サーバー間のリクエストには影響しません。
8a. 管理者キーを設定する(テナントごとのキー管理に必要)
ADMIN_KEY は、管理者 API(/v1/admin/keys)用のベアラートークンです。テナントごとの API キーを作成、一覧表示、取り消しできます。キャプチャや読み取りのアクセス権は付与されません。
キーを生成します。
openssl rand -hex 32
本番環境のシークレットを設定します。
wrangler secret put ADMIN_KEY
ローカル開発では、.dev.vars に追加します。
ADMIN_KEY=<hex string from the command above>
デプロイ後、最初のテナントキーを作成します。
curl -X POST https://api.webresourceledger.com/v1/admin/keys \
-H "Authorization: Bearer $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"tenantId": "default", "scopes": ["capture"], "name": "default-key"}' | jq .
以降は、返された key の値を $WRL_API_KEY として使用してください。移行手順の全容については、OPERATIONS.md を参照してください。
セキュリティ: この値をバージョン管理にコミットしないでください。.dev.vars はすでに .gitignore に追加されています。
8b. コンテンツのセキュリティスクリーニングを設定する(任意)
GOOGLE_WEB_RISK_API_KEY を設定すると、キャプチャ前および毎日の再スキャン時に URL の脅威をスクリーニングできます。設定しない場合、すべてのキャプチャで threatCheck: unavailable と報告され、URL はブロックされません。
Web Risk API を有効にした Google Cloud Console からキーを取得し、本番環境のシークレットを設定します。
wrangler secret put GOOGLE_WEB_RISK_API_KEY
ローカル開発では、.dev.vars に追加します。
GOOGLE_WEB_RISK_API_KEY=<your api key>
セキュリティ: この値をバージョン管理にコミットしないでください。.dev.vars はすでに .gitignore に追加されています。
9. デプロイする
wrangler deploy
手順 1~9 は初回のみ必要な設定です。初回のデプロイ後は、main へのプッシュごとに CD パイプラインがステージング環境と本番環境へのデプロイを自動で処理します。デプロイの全体的な流れ、環境設定、ロールバック手順、Worker の実行環境、GitHub CI、ローカル開発間でのシークレットの対応関係については、OPERATIONS.md を参照してください。
MCP サーバー
WRL は、キャプチャ、取得、一覧表示、検証という 4 つの主要な操作を、MCP ツールとして提供します。MCP 対応のエージェントや IDE であれば、HTTP クライアントコードを書かずにウェブページをキャプチャし、証拠を検証できます。
セットアップ手順とワークフローの例については、MCP Server Guide を参照してください。ローカルでの参照用として、docs/mcp.md では、Claude Code、Cursor、Windsurf、汎用クライアントに加え、すべてのツールについて説明しています。
ウェブ UI
WRL には、キャプチャを送信し、結果を閲覧するためのブラウザーベースのインターフェースが含まれています。WRL のデプロイ先で /ui にアクセスしてください。認証には、capture と read のスコープを持つ WRL API キーが必要です。
UI は Worker から直接提供されるため、別途ホスティングや CORS の設定は必要ありません。
開発
ローカル開発環境のセットアップ、テストの規約、コントリビューションのガイドラインについては、CONTRIBUTING.md を参照してください。
デプロイ、ロールバック、環境設定については、OPERATIONS.md を参照してください。
ステージング
wrangler.toml には、専用の R2 バケット、D1 データベース、KV ネームスペース(レート制限専用)を持つ [env.staging] 設定が含まれています。デプロイする前に、ご自身の Cloudflare アカウントでこれらのリソースを作成する必要があります(ステップ 2〜3 と同じですが、ステージングを対象とします)。
ステージング用の D1 データベースを作成します。
wrangler d1 create wrl-metadata-staging
wrangler.toml の [[env.staging.d1_databases]] にある database_id を更新してから、マイグレーションを適用します。
wrangler d1 migrations apply wrl-metadata-staging --env staging
ステージング用の KV ネームスペース(レート制限専用)を作成します。
wrangler kv namespace create KV --env staging
返された ID を使用して、wrangler.toml の [env.staging.kv_namespaces] にある id フィールドを更新します。
ステージング用の R2 バケットを作成します。
wrangler r2 bucket create wrl-captures-staging
その後、ステージングにデプロイします。
wrangler deploy --env staging
deploy-staging.yml により、main へのマージ時にステージングへ自動デプロイされます。ステージング環境用のシークレットは個別に設定する必要があります。
wrangler secret put CAPTURE_API_KEY --env staging
wrangler secret put SIGNING_KEY --env staging
# repeat for any other secrets
スモークテストは稼働中のデプロイに対して実行されます。SMOKE_URL と SMOKE_API_KEY を設定してから、次を実行します。
npm run smoke
ロードマップ
WRL は 3 幕構成の開発計画に沿って進められました。3 幕すべてが完了しています。
- 強固な基盤(完了) -- 一覧エンドポイント、キーのバージョン管理、CORS、セキュリティ強化。単一オペレーターでの利用における信頼性の隙間を解消しました。
- 証拠としての高い信頼性(完了) -- RFC 3161 タイムスタンプ、テナントごとのキー、監査ログ。キャプチャを独立して検証できるようにしました。
- インフラストラクチャ(完了) -- MCP サーバー、ウェブ UI、一括キャプチャ、スケジュールキャプチャ、ドキュメントサイト、ランディングページ、使用量の計測、ウェブフック。WRL をプラットフォームへと拡張しました。
継続中のバックログについては docs/backlog.md を、詳細な進捗管理については GitHub のイシューをご覧ください。
WRL の構築方法
WRL は本番環境で稼働するウェブ証拠サービスです。また、LLM 主導のソフトウェア開発を記録した実験でもあります。人間が構築するものを定義し、プロダクトに関する決定を行い、LLM(Claude)がコード、テスト、インフラストラクチャ、ドキュメントのほぼすべてを作成しました。
構築の全履歴は docs/evolution/ にあります。アーキテクチャ上の決定、エージェント間の意見の相違、人間による上書きなど、60 以上のフェーズを収録しています。本番規模での LLM 主導の開発が実際にどのようなものか関心がある方は、まずこちらをご覧ください。
リファレンス
キーのローテーション
キーのローテーションは安全です。ローテーション後も、過去のキャプチャは引き続き検証できます。キャプチャに署名するたびに、署名キーは自動的にアーカイブされます。各キーは keyId で識別されます。これは、未加工の 32 バイト公開鍵の SHA-256 の先頭 8 桁の 16 進数です。keyId は、WACZ バンドルの signedData.signatures 配列(v0.2.0)または signedData 直下(v0.1.0 レガシー)と、D1 のキャプチャレコードに保存されます。検証時には、現在のキーを前提とせず、keyId を使って適切な過去のキーを検索します。
ローテーションの手順:
- 新しいキーペアを生成します:
node scripts/generate-signing-key.js - 本番環境のシークレットを更新します:
wrangler secret put SIGNING_KEY - 必要に応じて、
.dev.varsのローカル開発用シークレットを更新します
新しいキャプチャには新しいキーで署名します。既存のキャプチャは、署名に使用されたアーカイブ済みのキーで検証されます。/.well-known/signing-keys エンドポイントには、サードパーティの検証者が利用できるキーアーカイブ全体が一覧表示されます。
公開鍵エンドポイント
GET /.well-known/signing-key は、現在の Ed25519 公開鍵を返します。サードパーティの検証者は、個々の WACZ バンドルに埋め込まれた publicKey を信頼せずに、この鍵を取得できます。レスポンスはエッジで 1 時間キャッシュされます。
{
"algorithm": "Ed25519",
"publicKey": "<base64-encoded raw 32-byte key>",
"keyId": "<8-char hex fingerprint>"
}
keyId は、未加工の公開鍵バイト列の SHA-256 の先頭 8 桁の 16 進数です。過去のキャプチャを検証する際に、キーアーカイブ内のキーとの照合に使用します。
キーアーカイブエンドポイント
GET /.well-known/signing-keys は、過去のすべての署名キーを一覧表示します。現在のキーだけでなく、どのキーで署名されたキャプチャも検証するには、このエンドポイントを使用してください。
{
"keys": [
{
"keyId": "<8-char hex fingerprint>",
"algorithm": "Ed25519",
"publicKey": "<base64-encoded raw 32-byte key>",
"archivedAt": "<ISO 8601 timestamp>"
}
]
}
サードパーティの検証ツールでは、WACZ バンドルの signedData(v0.1.0)または signedData.signatures 配列(v0.2.0)にある keyId をこの一覧と照合し、署名検証に適した公開鍵を取得してください。レート制限は単一キーのエンドポイントと同じです。
ヘルスエンドポイント
GET /health は、現在のサービスステータス、法的文書の URL、ビルド識別メタデータを返します。
{
"status": "ok",
"legal": { "terms": "<url>", "policy": "<url>" },
"build": { "commit": "<sha>", "version": "<semver>", "env": "production", "deployedAt": "<iso8601>" }
}
build オブジェクトは、CI 経由でデプロイされた場合に存在します(ビルド時に wrangler --define で挿入されます)。ローカル開発時には存在しません。稼働時間の監視、スモークテスト、デプロイの検証に役立ちます。
レスポンスヘッダー
すべてのレスポンスには、次のものが含まれます。
Link--rel="terms-of-service"を指定した利用規約の URL を示します。すべてのレスポンスに含まれます。Strict-Transport-Security--preloadとincludeSubDomainsを含みます。すべてのレスポンスに含まれます。X-RateLimit-Limit-- エンドポイントのレート制限上限です。レート制限のあるエンドポイント(キャプチャ、検証、署名キーエンドポイント)のレスポンスに含まれます。
法的情報
この API を使用することで、利用規約に同意したものとみなされます。
ライセンス
PolyForm Shield 1.0.0 -- ソースコードを利用できます。競合するウェブキャプチャサービスを提供する場合を除き、WRL はどのような目的でも使用、変更、セルフホストできます。全文については LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。