このページでは、マルチパーティ コンピューティング(MPC)Policy Engine が Cedar ポリシー言語で記述されたトランザクション ポリシーを評価し、クロスチェーン シナリオを処理し、オプションまたは省略されたメタデータ フィールドを解決する方法について説明します。
評価の基本原則
Policy Engine は、Cedar Policy Language を使用して暗号署名オペレーションを認可します。エンジンは、次の 3 つの基本公理を使用してポリシーを決定論的に評価します。
- デフォルト拒否: すべてのオペレーションが暗黙的に拒否されます。オペレーションが許可されるには、少なくとも 1 つのアクティブな
permitポリシーと一致する必要があります。一致するpermitポリシーが見つからない場合、最終的な決定はDENYになります。 - 明示的な禁止:
forbidポリシーは絶対的なオーバーライドとして機能します。オペレーションが有効なforbidポリシーに一致する場合、オペレーションを許可する一致するpermitポリシーに関係なく、決定は直ちにDENYに解決されます。 - フィールドがない場合は「一致なし」(スキップ)を意味する: ルールがトランザクション ペイロードに存在しないフィールド(省略されたオプション フィールドなど)を検索しても、Cedar はクラッシュしません。その特定のルールを「一致なし」として扱い(false と評価)、次のルールに進みます。
論理評価マトリックス
次の表は、Policy Engine がルールの組み合わせを評価する方法を示しています。
すべてのシナリオで、次のことを前提としてください。
- トランザクションの呼び出し元(Cedar ポリシーではプリンシパルとして表されます)は Alice(
User::"alice")です。マルチパーティ コンピューティングでは、プリンシパルは、暗号署名オペレーションの認可をリクエストするペルソナまたは ID(人間の署名者、自動サービス クライアント、バックエンド システム アカウントなど)を表します。 - このトランザクションでは、正確に 1 ETH(
context.transaction.spend_amount_scaledでは 1,000,000,000 スケール ナノコイン単位として表されます)が転送されます。
| シナリオ | 有効なポリシー | 結果 | 理由 |
|---|---|---|---|
| シナリオ 1: 空の状態 | 有効なポリシーはありません。 | DENY |
デフォルトでは、一致する permit ポリシーで明示的に許可されていない限り、すべてのオペレーションがブロックされます。 |
| シナリオ 2: 1 件の許可証が一致する |
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 10000000000 }; 最大 10 ETH まで可能 |
PERMIT |
トランザクション パラメータがポリシー条件を満たしている。競合する forbid ポリシーがないため、リクエストは許可されます。 |
| シナリオ 3: 1 つの許可証の不一致 |
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 500000000 }; 最大 0.5 ETH まで可能 |
DENY |
送金額(1 ETH)がポリシーの上限を超えています。一致する permit ルールが満たされていないため、デフォルトの拒否によってトランザクションがブロックされます。 |
| シナリオ 4: 複数の許可ポリシー |
ポリシー A: permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 500000000 }; 最大 0.5 ETH まで可能 ポリシー B: permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 5000000000 }; 最大 5 ETH まで可能 |
PERMIT |
ポリシー A は一致しませんが、ポリシー B は一致します。トランザクションを許可するには、一致する permit ポリシーが 1 つだけ必要です。 |
| シナリオ 5: 許可と禁止の競合 |
ポリシー A(許可): permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 5000000000 }; 最大 5 ETH まで可能 ポリシー B(禁止): forbid( principal == User::"alice", action, resource ) when { context.transaction.recipient == "0xBlockedAddress" }; 宛先が |
DENY |
転送は 0xBlockedAddress に送信されます。ポリシー A では取引金額が許可されていますが、宛先がポリシー B の条件に一致しています。明示的な forbid ルールがポリシー A をオーバーライドし、トランザクションをブロックします。 |
| シナリオ 6: 一致しない禁止ポリシー |
前のシナリオと同じポリシー |
PERMIT |
転送は安全なアドレス(0xSafeAddress など)に送信されます。ポリシー A は正常に一致し、ポリシー B は宛先が 0xBlockedAddress ではないため一致しません。一致する禁止ルールがない場合、許可ルールが適用されます。 |
マルチチェーンとオプション フィールドのシナリオ
上記の表は、許可ルールと禁止ルールの基本的な論理的優先順位を示していますが、次のシナリオは、Policy Engine がマルチチェーン環境でルールを評価する方法を示しています。具体的には、オプション フィールドまたは異なるブロックチェーン ネットワーク スキーマに対して実行する場合です。
注: ゼロ値データの正規化 予期しない評価エラーを防ぎ、ポリシーの予測可能性を確保するため、Policy Engine の解析レイヤは、評価コンテキストで入力されていない文字列フィールドとバイト フィールドを省略するのではなく、型固有のゼロ値(空の文字列
""や空のバイト配列など)に正規化します。この動作により、Cedar 評価エラーのリスクを冒すことなく、未入力のフィールドをターゲットとする明示的なポリシーをドラフトできます。ただし、ブロックチェーンのスキーマで完全に定義されていないフィールド(ビットコイン トランザクションの EVM 専用
gas_limit、EVM トランザクションのビットコイン専用outputsなど)にアクセスすると、その特定のポリシーで Cedar 評価エラーが発生し、false(一致なし)と評価され、安全にフェイルクローズされます。
シナリオ 7: クロスチェーン ポリシーの評価とマッピングされていないスキーマ属性
コンテキスト: 呼び出し元がビットコイン トランザクションを送信します。ただし、アクティブなポリシーセットには、Ethereum 固有のポリシーが含まれています。
permit( principal == User::"alice", action, resource ) when { context.transaction.schema == "ethereum.transaction.v2" && context.transaction.gas_limit < 100000 };結果:
DENY理由: ユニバーサル インテント属性(
spend_amount_scaled、recipient、max_fee_atomicなど)は、Ethereum トランザクションと Bitcoin トランザクションの両方で一貫して評価されます。ポリシーが、送信されたトランザクションのスキーマに存在しないチェーン固有の属性(ビットコイン トランザクションのgas_limitなど)を参照している場合、Cedar は一致しない属性を評価エラーとして扱い、エンジンを停止することなく、その特定のポリシーをfalse(一致なし)に解決します。ビットコイン トランザクションに一致する他のアクティブなpermitポリシーがないため、オペレーションはデフォルトで拒否されます。
シナリオ 8: permit ポリシーにオプション フィールドがない
コンテキスト: 呼び出し元が標準の ETH 送金(スマート コントラクトを使用しない)を送信します。アクティブなポリシーセットには、コントラクトのやり取りをチェックするルールが含まれています。
permit( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "0x1111111111111111111111111111111111111111" };結果:
DENY理由: 標準の ETH 転送では、オプションの
asset_contract_addressは入力されません。パーサーは、これを評価コンテキストのゼロ値の空の文字列""に正規化します。比較"" == "0x1111..."を評価すると、エラーが発生するのではなく、false(一致なし)が返されます。他のポリシーで転送が許可されていないため、このオペレーションはデフォルトで拒否されます。
シナリオ 9: forbid ポリシーにオプション フィールドがない
コンテキスト: 呼び出し元が 10 ETH の標準的な ETH 送金を送信します。ポリシーセットは次の要素で構成されます。
ポリシー A(許可):
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled <= 100000000000 };ポリシー B(禁止):
forbid( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "0xBannedContract" };
結果:
PERMIT理由: 10 ETH は上限を下回っているため、ポリシー A が正常に一致します。ポリシー B は、契約アドレスが禁止アドレスと一致するかどうかを確認します。ゼロ値の正規化により、未入力のコントラクト アドレスは
""に解決されます。比較"" == "0xBannedContract"を評価すると、falseが返されます。禁止ポリシーは一致せず、許可ポリシーは一致するため、トランザクションは許可されます。
シナリオ 10: 空のフィールドまたは欠落しているフィールドの明示的なチェック
コンテキスト: 呼び出し元が標準の ETH 送金(スマート コントラクトに送信されない)を送信します。ポリシーセットは次の要素で構成されます。
ポリシー A(許可):
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled <= 1000000000000 };ポリシー B(禁止):
forbid( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "" };
結果:
DENY理由: パーサーの正規化により、欠落している
asset_contract_addressは評価コンテキストで空の文字列""として表示されます。ポリシー B を評価すると、条件がtrue("" == "")に解決されます。forbidポリシーが一致し、トランザクションが拒否されます。
評価前の検証(フェイルファスト ゲート)
Policy Engine は厳格なデータ検証を適用します。ペイロードがポリシー評価のために Cedar に渡される前に、基盤となるパーサーがトランザクション構造、RLP エンコード、暗号の整合性を検証します。
シナリオ 11: 不正な形式の無効なトランザクション ペイロード
- コンテキスト: クライアントが、不正な形式のバイト シーケンス、無効な構造のペイロード、または必須の暗号フィールドが欠落しているトランザクション(無効な RLP 構造またはガス パラメータが欠落している EVM トランザクションなど)を送信します。
- 結果:
gRPC InvalidArgument - 理由: 内部トランザクション パーサーが API Gateway レイヤで無効な入力を検出します。オペレーションはすぐに失敗して終了し、クライアントに
gRPC InvalidArgumentエラーを返します。Cedar Policy Engine による評価は完全にバイパスされます。