sdcreceipt について
sdcreceiptは、VSL Settlement Receiptの検証と決済を行う小規模なクライアントです。レシートと別に鍵を指定し、オフラインでの署名確認と制御された決済承認に対応します。
主な機能
- 01オフラインでのレシート検証
- 02決済の作成と署名
- 03当事者鍵のセットアップ
- 04発行者と当事者の署名確認
- 05ペイロードとガバナンスの任意確認
活用シーン
- 01発行者に接続せずレシートを検証
- 02当事者として決済を承認
- 03ペイロードやガバナンスの結び付きを確認
- 04シェルスクリプトに検証を組み込む
MCP 対応
MCPサーバーは `verify_receipt`、`sign_trigger`、`settle` を公開します。`settle` には起動時に固定エンドポイントとトークンが必要で、署名鍵も起動時に指定します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
1掲載時のツール一覧 · 3 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| receipt | object | はい | 検証する Settlement Receipt ドキュメントです。 |
| party_keys | object | いいえ | 任意。トリガーを検証するための当事者鍵ドキュメントです。省略するとトリガーチェックをスキップします。鍵を保有していない場合に省略するのは適切であり、その旨が結果に示されます。 |
| issuer_keys | object | はい | 発行者が公開している JSON 形式の鍵ドキュメントです。`keys` 配列を含む鍵セット形式、または did:web DID ドキュメントを指定できます。 |
| governance_receipt | object | いいえ | 任意。保有している場合はガバナンス Receipt を指定します。 |
詳細
sdcreceipt
VSL Settlement Receipt を検証して精算します。
検証にアカウント、ネットワーク、発行者からの情報は必要ありません。 誰もが独立して Receipt を確認できるという主張には、それを実行できる能力と同じだけの価値があります。このツールの意義はそこにあります。
Apache-2.0。
pip install sdcreceipt
4 つの動詞
# Check a Receipt you were sent. Offline.
sdcreceipt verify receipt.json --issuer-keys issuer-keys.json --party-keys party-keys.json
# Set yourself up as a party: keypair + the document to publish.
sdcreceipt init --key-id https://vendor.example/.well-known/vsl-key.json
# Authorize a settlement you are a party to.
sdcreceipt trigger receipt.json --key vsl-party.pem \
--key-id https://vendor.example/.well-known/vsl-key.json
# Ask an issuer for a Receipt. The one verb that needs an account.
sdcreceipt settle payload.xml \
--party https://vendor.example/.well-known/vsl-key.json \
--party did:web:partner.example
settle は、指定されていない必要な情報をすべて尋ねます。ただし current_state は例外で、ペイロード自身の <current-state> がデフォルト値になります。Receipt を --out(または標準出力)に書き込み、verify と trigger ですぐに使える状態にします。--response FILE を指定すると、発行者の回答全体(ガバナンス上の判断と請求額)も保存します。DENY は発行され、署名されますが、トリガーは受け付けません。settle はその旨を伝えます。2 つのフィールドは推測できるものではなく、今後もそうなることはありません。リリース条件は発行者がハッシュ化し、保存しません。また、current_state/target_state は、あなたではなく発行者が保持するスキーマで定義されたガバナンスのワークフローから取得されます。
発行者が状態遷移を拒否すると、受け入れ可能な状態遷移を回答し、settle がそれらを表示します。
Governance evaluation produced no Receipt. Decision was DENY
From 'draft' you can go to: review
This model's workflow:
standard: draft -> review -> published
この場合は終了コード 2、実際のエラーの場合は 1 で終了するため、スクリプトで「条件を変えて再試行する」場合と「何かが壊れている」場合を区別できます。
verify はすべてのチェックに合格した場合のみ終了コード 0 を返すため、出力を解析しなくてもシェル内で組み合わせて使えます。
これがすべての機能です。これはクライアントであり、製品ではありません。読み解けるほど小さいことに価値があります。
何も読まずに試す
python examples/settle.py
2 者間で 2 つの署名を使い、オフラインで検証する、一連の精算を最初から最後まで行えます。アカウント、ネットワーク、API キーは不要です。examples/ を参照してください。
エージェント向け
4 つの動詞のうち 3 つを、同じパッケージ内で MCP 経由で利用できます。
sdcreceipt-mcp --key vsl-party.pem \
--key-id https://vendor.example/.well-known/vsl-key.json
verify_receipt、sign_trigger、settle を公開します。各ツールは、サーバーに必要なものがそろっている場合にのみ公開されるため、どの呼び出しも失敗するツールが提示されることはありません。
意図的に設けた 2 つの制限があります。これは見落としではなく、セキュリティ上の方針です(SECURITY.md も参照してください)。
- 鍵の生成は行いません。 エージェントのセッション内で生成された秘密鍵は、保管方法が明確ではありません。
initは引き続き、ターミナルで人間が行う操作です。 - 送信は行いません。
sign_triggerは、送信用の署名済みトリガーを返します。送信には呼び出し元が指定する宛先が必要であり、署名済みトリガーと任意のホストを組み合わせることは、拒否すべきものです。
settle は --endpoint とトークンを指定してサーバーを起動した場合に利用でき、ネットワークに接続する唯一のツールです。エンドポイントは鍵と同様、起動時に固定されるため、呼び出し元がペイロードの送信先を変更することはできません。URL を受け取るツールはありません。 今後ツールを追加する場合も、この不変条件を維持する必要があります。
署名鍵は起動時に渡され、ツール呼び出しで渡されることはありません。そのため、会話を介して送られることもありません。
Receiptを受け取った場合
誰かのアカウントは必要ありません。発行者が公開しているキードキュメントと、決済済みのReceiptの場合は各当事者のキードキュメントが必要です。Receiptでは、各当事者を公開鍵のURIで示します。発行者のキードキュメントは、固定の既知パスにあります。
pip install sdcreceipt
curl -o receipt.json https://sdcstudio.axius-sdc.com/api/v1/vsl/receipt/<receipt id> # or the file you were sent
curl -O https://sdcstudio.axius-sdc.com/.well-known/sdcstudio-signing-keys.json
curl -o vendor-keys.json https://vendor.example/.well-known/vsl-key.json
curl -o partner-keys.json https://partner.example/.well-known/did.json
sdcreceipt verify receipt.json --issuer-keys sdcstudio-signing-keys.json \
--party-keys vendor-keys.json --party-keys partner-keys.json
発行者のドキュメントでは発行者の署名を検証し、各当事者のドキュメントではその当事者のトリガーのみを検証します。
役割はReceiptではなくコマンドラインで指定します。また、2つのドキュメントが同じkey_idを主張している場合は拒否されます。
4.3.3以降、古い--keysフラグは拒否されます。すべてのドキュメントをひとまとめにしていたため、当事者自身のドキュメントで発行者のキーを指定できてしまっていました(GHSA-gwhr-82j5-883w)。
チェック後、verifyはVERIFIEDでカバーされない項目を一覧表示します。トリガーのタイムスタンプは署名されていないこと、キーの有効期間がReceiptの時刻と比較されないこと、チェーンリンク(previous_hash)がたどられないこと、ペイロードとガバナンスReceiptは指定した場合にのみチェックされることです。
最初の失敗だけでなく、すべてのチェック結果が報告されます。
PASS receipt_hash: matches the canonical content
PASS signature[sdcstudio-signing-key-v1]: verifies over receipt_hash (ES256)
PASS signature[sdcstudio-pq-signing-key-v1]: verifies over receipt_hash (ML-DSA-65)
PASS signatures.algorithms: carries every signature version 1.1 requires (ES256, ML-DSA-65)
PASS trigger[https://vendor.example/.well-known/vsl-key.json]: verifies over {condition_hash, receipt_id}
PASS trigger[did:web:partner.example]: verifies over {condition_hash, receipt_id}
PASS triggers.unique: one trigger per party
PASS settlement.complete: every listed party has triggered
VERIFIED
発行者のドキュメントだけを指定した場合、発行者の署名とハッシュがチェックされ、settlement.completeは未確認として記録されるため、Receiptは検証に合格しません。すべての当事者がトリガーしたかどうかは認可に関する主張であり、トリガー署名がチェックされていないためです。これは不具合ではなく、正しい結果です。Receiptの形状も先にチェックするには、--schema settlement-receipt-1.0.schema.json(またはReceiptのversionに合わせて-1.1)も指定してください(pip install 'sdcreceipt[schema]')。
Receipt 1.1(4.3.0以降)は、1.0に対して発行者が同じ32バイトのダイジェストに署名した、ES256とML-DSA-65(FIPS 204、耐量子)の2つの署名を追加したものです。一覧にあるすべての署名が検証に合格する必要があり、1.1を示すReceiptには両方の署名が必要です。1.0のReceiptは、これまでとまったく同じ方法で検証されます。発行者のキードキュメントには、各キーのalgとともに両方のキーが記載されます。ML-DSA-65の検証にはcryptography 48以降が必要で、このツールはそれを要求します。
Receiptに含まれるのはハッシュコミットメントのみで、ペイロードは含まれません。そのため、検証によって、適合性があり認可された、両者がトリガーしたやり取りが行われたと確認できますが、やり取りの内容を誰かが開示する必要はありません。ペイロードまたはガバナンスReceiptも手元にある場合は、それらを指定すると、そちらもチェックされます。
sdcreceipt verify receipt.json --issuer-keys issuer-keys.json --party-keys party-keys.json \
--payload manifest.xml --governance governance-receipt.json
当事者になる必要がある場合
決済では、各当事者を、あなたが管理するkey_idで識別します。これは意図的な設計です。署名の検証が発行者を経由しなくなるため、過去の署名が意味を持ち続けるために誰かが稼働し続ける必要はありません。
sdcreceipt init --key-id https://vendor.example/.well-known/vsl-key.json
これにより、秘密鍵(モード0600)とキードキュメントが作成され、ドキュメントにアクセスできるようにする必要がある正確なURLが表示されます。JSONファイルを1つ公開するだけで、オンボーディング要件をすべて満たせます。
次に、認可するReceiptを受け取ったら、以下を実行します。
sdcreceipt trigger receipt.json --key vsl-party.pem --key-id <your key_id>
署名済みのトリガーが出力され、そこで処理が停止します。署名は何も実行しませんが、送信は副作用を伴います。そのため、自分で送信するか、--submit <url>を追加してください。
★ ドキュメントから検証鍵を決して取得しないでください
受け入れる鍵の集合は、ドキュメントを読む前に決定されます。 ドキュメントによって変更されることはありません。
XML-Signature の ds:RetrievalMethod、JOSE の jku と x5u、および他の場所にある同等の仕組みは、いずれも「ここに鍵があります」と示すものです。そのポインターはドキュメントを作成した者が記述したものです。したがって、それに従うと、ドキュメント自身に自分を審査する鍵を選ばせることになります。偽造されたドキュメントは偽造者の鍵を指定し、検証は「成功」します。
この問題は気付かれにくいものです。ドキュメントに署名した時点では正しかったドメインをポインターが指していても、その後に期限切れになることがあります。そのドメインを登録した者は誰でも、そのパスで鍵を配信できます。ドキュメント自体には何の問題もないように見えます。実際、ドキュメント自体に問題はありません。検証者は参照先を尋ねられ、指示どおりにしただけです。
このツールでは、そのような間違いは起こりません。verify は引数として鍵を受け取り、鍵を取得するコードパスを持たないためです。これは不便ではなく、セキュリティ上の特性です。
パーティーの鍵にも同じことが当てはまりますが、例外ではなく、補足があります。key_id は意図的に、相手方が管理する URI です。信頼できる Receipt にすでに記録されている識別子に対してのみ、HTTPS 経由で解決し、コピーを保管してください。後にドメインを失ったパーティーが、過去の署名の意味を変更できてはなりません。
パーティーの鍵も指定してください。鍵がなくても発行者の署名とペイロードのハッシュは検証できるという意味では、パーティーの鍵は任意です。しかし、決済済みの Receipt がそれらなしでも意味を持つという意味ではありません。すべてのパーティーがトリガーしたかどうかは、認可に関する主張です。そのため、署名と照合する鍵がない場合、settlement.complete は合格ではなく未確立として記録され、Receipt は検証されません。4.2.1 より前のバージョンでは、key_id 文字列だけを比較して合格としていたため、偽造されたトリガーに対して VERIFIED と報告していました。
適合性
tests/conformance/ には発行元が公開したベクトルが含まれており、テストスイートはこの実装をそれらに照らして実行します。
16 個のベクトルがあり、Receipt 1.0 が 11 個、1.1 が 5 個です(それぞれ、名前が示す独自の version のスキーマに照らして検証されます)。無効な各ベクトルは、実際に発生した欠陥を符号化したものであり、仮定上のものではありません。ES256 で P1363 が必要な箇所に DER 署名を使ったもの、receipt_hash の生バイトではなく 16 進テキストに対する署名、保持している証拠と一致しないガバナンスバインディング、同じリリース条件を共有する別の Receipt からトリガーを再生したものなどです。誤った理由で失敗しても合格とは見なされません。マニフェストには、失敗すべき検査が記載されています。
pytest
独立性について、率直に述べます。 これらのベクトルに合格することは、このツールが発行元の公開した期待に一致し、そこから逸脱していないことを示します。独立した再導出ではありません。 この実装と発行元は、設計と経緯を共有しています。これらのベクトルが最も役立つのは、仕様だけを基に検証ツールを作成する人です。その目的で公開されています。
その基盤となる正準化は別の話であり、独立した実装との照合で検証されています。 Receipt 内の各ハッシュは RFC 8785 の正準バイト列を対象として計算されるため、正準化の一致が、それ以降の検証すべての土台となります。2026 年 9 月、この一致は、sdcgovernance ではなく Trail of Bits の rfc8785 を使って RFC 8785 を実装している MTCP プロジェクト(Ahmad Abby)と、双方向で検証されました。
- MTCP が公開した 5 つのベクトルを
sdcgovernance.jcsで実行しました。すべてのベクトルで、正準文字列と SHA-256 がバイト単位で一致しました。このセットは 2026 年 9 月 9 日に公開された、実際のスキーマに合成値を使用したクリーンな再生成版です。含まれる値はaudit_record、evaluation_summary、score_record、sensor_calibration、arabic_contentです。これは 9 月 1 日の 4 ベクトルセットに取って代わるもので、正準形式を含むフィールド名がcanonical_hexからoutputに変更されています。そのため、以前のセットを対象に作成されたランナーは更新が必要です。 sdcgovernance/test-vectors/rfc8785-canonicalization.jsonの 21 個のベクトルを MTCP の実装に対して実行しました。不一致はゼロでした。エッジケースのセットには、負のゼロ、サブノーマル数、1e21 の固定小数点表記から指数表記への境界、C0 制御文字の小文字\u00xx表記、エスケープされないスラッシュ、補助平面の文字、UTF-16 サロゲートペアをまたぐキー順序が含まれます。- MTCP は、cyberphone Appendix G の参照ベクトルに対する純粋な RFC 8785 テスト 19 件の適合性テスト実行結果を公開しています。公式ベクトル 6 件と 16 進検証、ハードエラーとして拒否されるケース 10 件(NaN、無限大、2^53 を超える整数、JSON 以外の型)、数値書式のケース 1 件、整数境界のケース 1 件、そして 2011 個の IEEE-754 パターンに対する Node.js との差分テスト(不一致ゼロ)です。
両者はそれぞれ独立して Node.js との差分テストを実行しているため、数値書式は再実装したものではなく、JS エンジンと照合されています。RFC 8785 §3.2.2.3 は ECMAScript の Number::toString をそのまま採用しているため、実際に問題が起きる部分についてはエンジンが参照基準になります。2 つの言語にまたがる 3 つの実装で、不一致はありません。これは、どちらのプロジェクトも単独では主張できないことであり、同じ系譜からのセカンドオピニオンよりも、こちらを優先すべき理由です。
ただし、これによって上記の Receipt ベクトルが独立したものになるわけではありません。意味するのは、ベクトルとあなたの実装が食い違ったとき、その不一致は基盤となるバイト列ではなく、Receipt のルールに関するものだということです。
独自に構築する
このツールを使う必要はなく、仕様もこのツールには依存しません。 検証ツールを作成する場合:
2つ目の正規化器を作成しないでください。 sdcgovernance または RFC 8785 に準拠した別の実装を使用してください。2つ目の実装は最初の実装と異なる結果になる可能性があり、その不一致は気づかれないまま発生します。バイト列が異なるためハッシュも異なり、成果物は誤ってエンコードされたものではなく、改ざんされたものとして扱われます。このツールが sdcgovernance.jcs を再エクスポートし、ほかに何も追加していないのは、まさにそのためです。
推測せずに拒否してください。 ±(2⁵³−1) を超える整数は IEEE 754 の倍精度浮動小数点数を経由すると元に戻せず、NaN/Infinity は JSON で表現できません。これらの値に対して何かを出力すると、一見問題のないハッシュが生成されますが、ほかの人の検証ツールでしか失敗が判明しません。
すべてのチェック結果を報告してください。 最初の失敗で停止すると、最も重要なケース、つまり署名は検証できてもガバナンスのバインディングが一致しない Receipt が見えなくなります。
曲線を確認してください。 予期しない曲線上の鍵に対して署名を検証しても、署名したと考えている当事者について何の証明にもなりません。
バージョニング
MAJOR は SDC リファレンスモデルに対応するため、4.x.x リリースは SDC4 を対象とします。以前に3つのバージョンがあったからではなく、この規則に従っているため、4から始まります。MINOR は機能、PATCH は修正です。SDC5 のリファレンスモデルでは、バージョンは 5.x.x になります。
sdcvalidator、sdcgovernance をはじめとする同系列のパッケージでも同じ方式が使われるため、バージョン番号を見れば、調べなくても成果物が対象とするリファレンスモデルがわかります。
Receipt のフォーマットバージョンは別個のもので、独立しています。 Receipt にはワイヤーフォーマットとして "version": "1.0" または "1.1" と記載され、このパッケージのバージョンではありません。1.1 の検証に対応した最初のリリースは 4.3.0 です。それ以前のリリースは、フォーマットの要件に従い、推測せずにバージョンを理由として拒否します。
依存関係
Python 3.10 以降。
直接依存関係は2つで、どちらも Apache-2.0 と互換性のあるライブラリです。RFC 8785 の正規化には sdcgovernance(>=4.2.0,<5 に固定)、ECDSA には cryptography を使用します。jsonschema はオプションで、--schema にのみ必要です。クリーンな環境で pip install sdcreceipt を実行すると、この2つとそれぞれの依存関係、合計約14個のパッケージがインストールされます。pip install --report を使うと、お使いのプラットフォームに対応する正確なパッケージ一覧を確認できます。
これらはライブラリの依存関係です。このツールはサービスを呼び出さず、verify はネットワークリクエストを一切行いません。settle と trigger --submit は、ローカル発行者向けのループバックを除き、https:// 以外のエンドポイントを拒否します。
セキュリティ
脆弱性の報告方法、サポート対象のバージョン、このツールが保護するものと保護しないものについては、SECURITY.md を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。