Cedar によるポリシーの評価

このページでは、マルチパーティ コンピューティング(MPC)Policy Engine が Cedar ポリシー言語で記述されたトランザクション ポリシーを評価し、クロスチェーン シナリオを処理し、オプションまたは省略されたメタデータ フィールドを解決する方法について説明します。

評価の基本原則

Policy Engine は、Cedar Policy Language を使用して暗号署名オペレーションを認可します。エンジンは、次の 3 つの基本公理を使用してポリシーを決定論的に評価します。

  1. デフォルト拒否: すべてのオペレーションが暗黙的に拒否されます。オペレーションが許可されるには、少なくとも 1 つのアクティブな permit ポリシーと一致する必要があります。一致する permit ポリシーが見つからない場合、最終的な決定は DENY になります。
  2. 明示的な禁止: forbid ポリシーは絶対的なオーバーライドとして機能します。オペレーションが有効な forbid ポリシーに一致する場合、オペレーションを許可する一致する permit ポリシーに関係なく、決定は直ちに DENY に解決されます。
  3. フィールドがない場合は「一致なし」(スキップ)を意味する: ルールがトランザクション ペイロードに存在しないフィールド(省略されたオプション フィールドなど)を検索しても、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"
};

宛先が 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 による評価は完全にバイパスされます。