使用 Cedar 进行政策评估

本页面介绍了多方计算 (MPC) 政策引擎如何评估用 Cedar 政策语言编写的交易政策、如何处理跨链场景,以及如何解析可选或省略的元数据字段。

核心评估原则

政策引擎使用 Cedar 政策语言来授权加密签名操作。该引擎使用三个基本公理确定性地评估政策:

  1. 默认拒绝:所有操作都会被隐式拒绝。操作必须至少与一项有效的 permit 政策匹配,才能获得许可。如果未找到匹配的 permit 政策,则最终决定为 DENY。
  2. 明确禁止:forbid 政策具有绝对覆盖效力。如果某项操作与任何有效的 forbid 政策匹配,则该操作会立即被判定为 DENY,无论是否有任何匹配的 permit 政策会允许该操作。
  3. Missing Fields Just Mean "No Match" (Skip):如果规则查找的字段在事务载荷中不存在(例如被省略的 Options 字段),Cedar 不会崩溃。它会将该特定规则视为“不匹配”(求值结果为 false),并继续执行下一条规则。

逻辑评估矩阵

下表展示了政策引擎如何评估规则组合。

对于所有场景,假设:

  • 交易调用方(在 Cedar 政策中表示为主账号)是 Alice (User::"alice")。在多方计算中,主账号表示请求对加密签名操作进行授权的角色或身份(例如人工签名者、自动化服务客户端或后端系统账号)。
  • 该交易正好转移 1 ETH(在 context.transaction.spend_amount_scaled 中表示为 1,000,000,000 个缩放的纳米币单位)。
场景 有效政策 结果 原因
场景 1:空白状态 没有有效政策。 DENY 默认情况下,所有操作都会被屏蔽,除非匹配的 permit 政策明确允许。
场景 2:单个许可匹配
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 10000000000
};

最多允许 10 ETH

PERMIT 交易参数满足政策条件。由于没有冲突的 forbid 政策,因此允许该请求。
场景 3:单个许可证不匹配
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 政策即可允许交易。
场景 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。如果没有匹配的禁止规则,则应用允许规则。

多链和可选字段场景

虽然上述矩阵展示了允许规则和禁止规则的核心逻辑优先级,但以下场景说明了政策引擎如何在多链环境中评估规则:具体而言,是在针对可选字段或不同区块链网络架构执行规则时。

注意: 零值数据标准化 为防止出现意外的评估错误并确保政策的可预测性,政策引擎的解析层会将评估上下文中未填充的字符串和字节字段标准化为其类型特定的零值(例如空字符串 "" 或空字节数组),而不是将其省略。

这样,您就可以针对未填充的字段起草明确的政策,而不会有 Cedar 评估错误的风险。不过,如果访问区块链架构中完全未定义的字段(例如,在比特币交易中访问仅限 EVM 的 gas_limit,或在 EVM 交易中访问仅限比特币的 outputs),则会导致该特定政策出现 Cedar 评估错误,从而导致其评估结果为 false(不匹配),并安全地失败关闭。

场景 7:跨链政策评估和未映射的架构属性

  • 背景:调用方提交比特币交易。不过,有效政策集包含一项以太坊专用政策:

    permit(
      principal == User::"alice",
      action,
      resource
    )
    when {
      context.transaction.schema == "ethereum.transaction.v2" &&
      context.transaction.gas_limit < 100000
    };
    
  • 结果: DENY

  • 原因:通用 intent 属性(例如 spend_amount_scaled、recipient 和 max_fee_atomic)在以太坊和比特币交易中的评估方式一致。当政策引用提交的交易架构中不存在的链特定属性(例如比特币交易中的 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 政策中缺少可选字段

  • Context: A caller submits a standard ETH transfer of 10 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

  • 原因:政策 A 成功匹配,因为 10 ETH 低于限额。政策 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 政策匹配,交易被拒绝。


预评估验证(快速失败门控)

政策引擎会强制执行严格的数据验证。在将载荷传递给 Cedar 进行政策评估之前,底层解析器会验证交易结构、RLP 编码和加密完整性。

场景 11:格式错误和无效的事务载荷

  • 背景:客户端提交了格式错误的字节序列、结构无效的载荷或缺少强制性加密字段的交易(例如,RLP 结构无效或缺少 gas 参数的 EVM 交易)。
  • 结果: gRPC InvalidArgument
  • 原因:内部事务解析器在 API Gateway 层检测到无效输入。操作会立即失败并关闭,向客户端返回 gRPC InvalidArgument 错误,并且完全绕过 Cedar 政策引擎的评估。