Evaluación de políticas con Cedar

En esta página, se describe cómo el motor de políticas de computación multipartita (MPC) evalúa las políticas de transacciones escritas en el lenguaje de políticas Cedar, controla las situaciones de cadena cruzada y resuelve los campos de metadatos opcionales o que se omitieron.

Principios básicos de la evaluación

El Policy Engine usa el lenguaje de políticas de Cedar para autorizar operaciones de firma criptográfica. El motor evalúa las políticas de forma determinística con tres axiomas fundamentales:

  1. Denegación predeterminada: Todas las operaciones se deniegan de forma implícita. Para que se permita una operación, debe coincidir con al menos una política de permit activa. Si no se encuentra ninguna política de permit coincidente, la decisión final es DENY.
  2. Prohibición explícita: Una política forbid actúa como una anulación absoluta. Si una operación coincide con alguna política de forbid activa, la decisión se resuelve de inmediato como DENY, independientemente de cualquier política de permit coincidente que, de lo contrario, permitiría la operación.
  3. Los campos faltantes solo significan "No hay coincidencia" (omitir): Si una regla busca un campo que no está presente en la carga útil de la transacción (como un campo opcional que se omitió), Cedar no falla. Trata esa regla específica como una "no coincidencia" (se evalúa como falsa) y pasa a la siguiente regla.

Matriz de evaluación lógica

En la siguiente tabla, se muestra cómo Policy Engine evalúa las combinaciones de reglas.

Para todas las situaciones, supón lo siguiente:

  • La persona que llama a la transacción (representada como la principal en las políticas de Cedar) es Alice (User::"alice"). En la computación multipartita, una principal representa la persona o identidad que solicita autorización para una operación de firma criptográfica (como un firmante humano, un cliente de servicio automatizado o una cuenta de sistema de backend).
  • La transacción transfiere exactamente 1 ETH (representado como 1,000,000,000 de unidades de nanocoin escaladas en context.transaction.spend_amount_scaled).
Situación Políticas activas Resultado Motivo
Situación 1: Estado vacío No hay políticas activas. DENY De forma predeterminada, se bloquean todas las operaciones, a menos que una política de permit coincidente las permita de forma explícita.
Situación 2: Coincidencia con un solo permiso
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 10000000000
};

Permite hasta 10 ETH

PERMIT Los parámetros de la transacción cumplen con la condición de la política. Como no hay políticas forbid en conflicto, se permite la solicitud.
Situación 3: No coincidencia de un solo permiso
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 500000000
};

Permite hasta 0.5 ETH

DENY El importe de la transferencia (1 ETH) supera el límite de la política. Como no se cumple ninguna regla de permit coincidente, la denegación predeterminada bloquea la transacción.
Situación 4: Varias políticas de permiso

Política A:

permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 500000000
};

Permite hasta 0.5 ETH

Política B:

permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 5000000000
};

Permite hasta 5 ETH

PERMIT Aunque la política A no coincide, la política B sí. Solo necesitas una política de permit que coincida para permitir la transacción.
Situación 5: Conflicto entre Permitir y Prohibir

Política A (permitir):

permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 5000000000
};

Permite hasta 5 ETH

Política B (prohibir):

forbid(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.recipient == "0xBlockedAddress"
};

Se supone que el destino es 0xBlockedAddress

DENY La transferencia se envía a 0xBlockedAddress. Aunque la Política A permite el importe de la transacción, el destino coincide con los criterios de la Política B. La regla explícita forbid anula la política A y bloquea la transacción.
Situación 6: Política de prohibición sin coincidencias

Las mismas políticas que en la situación anterior

PERMIT La transferencia se envía a una dirección segura (p.ej., 0xSafeAddress). La política A coincide correctamente y la política B no coincide porque el destino no es 0xBlockedAddress. En ausencia de una regla de prohibición coincidente, se aplica la regla de permiso.

Situaciones de cadenas múltiples y campos opcionales

Si bien la matriz anterior demuestra la precedencia lógica principal de las reglas permitidas y prohibidas, las siguientes situaciones ilustran cómo el Policy Engine evalúa las reglas en un entorno de varias cadenas: específicamente, cuando se ejecuta en campos opcionales o diferentes esquemas de red de cadena de bloques.

Nota: Normalización de datos con valor cero Para evitar errores de evaluación inesperados y garantizar la previsibilidad de las políticas, la capa de análisis de Policy Engine normaliza los campos de cadena y bytes sin completar en el contexto de evaluación a sus valores cero específicos del tipo (como una cadena vacía "" o un array de bytes vacío) en lugar de omitirlos.

Este comportamiento te permite redactar políticas explícitas orientadas a campos sin completar sin correr el riesgo de que se produzcan errores de evaluación de Cedar. Sin embargo, acceder a campos que no están definidos en el esquema de una cadena de bloques (como gas_limit, que solo se aplica a EVM, en una transacción de Bitcoin, o outputs, que solo se aplica a Bitcoin, en una transacción de EVM) generará un error de evaluación de Cedar en esa política específica, lo que hará que se evalúe como false (sin coincidencia) y falle de forma segura.

Situación 7: Evaluación de políticas entre cadenas y atributos de esquema no asignados

  • Contexto: Un emisor envía una transacción de Bitcoin. Sin embargo, el conjunto de políticas activo contiene una política específica de Ethereum:

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

  • Motivo: Los atributos de intent universales (como spend_amount_scaled, recipient y max_fee_atomic) se evalúan de manera coherente en las transacciones de Ethereum y Bitcoin. Cuando una política hace referencia a atributos específicos de la cadena que no existen en el esquema de la transacción enviada (como gas_limit en una transacción de Bitcoin), Cedar trata el atributo no coincidente como un error de evaluación, lo que resuelve esa política específica como false (sin coincidencia) sin detener el motor. Como ninguna otra política activa de permit coincide con la transacción de Bitcoin, la operación se rechaza de forma predeterminada.

Situación 8: Falta un campo opcional en una política de permit

  • Contexto: Un emisor envía una transferencia de ETH estándar (que no usa contratos inteligentes). El conjunto de políticas activo contiene una regla que verifica las interacciones del contrato:

    permit(
      principal == User::"alice",
      action,
      resource
    )
    when {
      context.transaction.asset_contract_address == "0x1111111111111111111111111111111111111111"
    };
    
  • Resultado: DENY

  • Motivo: En una transferencia de ETH estándar, el campo opcional asset_contract_address no se completa. El analizador normaliza esto a la cadena vacía de valor cero "" en el contexto de evaluación. La evaluación de la comparación "" == "0x1111..." devuelve false (no hay coincidencia) en lugar de generar un error. Como ninguna otra política permite la transferencia, la operación se rechaza de forma predeterminada.

Situación 9: Falta un campo opcional en una política de forbid

  • Contexto: Un emisor envía una transferencia estándar de 10 ETH. El conjunto de políticas consta de lo siguiente:

    • Política A (permitir):

      permit(
        principal == User::"alice",
        action,
        resource
      )
      when {
        context.transaction.spend_amount_scaled <= 100000000000
      };
      
    • Política B (prohibir):

      forbid(
        principal == User::"alice",
        action,
        resource
      )
      when {
        context.transaction.asset_contract_address == "0xBannedContract"
      };
      
  • Resultado: PERMIT

  • Motivo: La política A coincide correctamente porque 10 ETH está por debajo del límite. La política B verifica si la dirección del contrato coincide con una dirección prohibida. Debido a la normalización de valor cero, la dirección del contrato sin propagar se resuelve como "". La evaluación de la comparación "" == "0xBannedContract" devuelve false. Dado que la política de prohibición no coincide y la de permiso sí, se permite la transacción.

Situación 10: Verificación explícita de campos vacíos o faltantes

  • Contexto: Un emisor envía una transferencia de ETH estándar (que no se envía a un contrato inteligente). El conjunto de políticas consta de lo siguiente:

    • Política A (permitir):

      permit(
        principal == User::"alice",
        action,
        resource
      )
      when {
        context.transaction.spend_amount_scaled <= 1000000000000
      };
      
    • Política B (prohibir):

      forbid(
        principal == User::"alice",
        action,
        resource
      )
      when {
        context.transaction.asset_contract_address == ""
      };
      
  • Resultado: DENY

  • Motivo: Debido a la normalización del analizador, el asset_contract_address faltante se presenta en el contexto de evaluación como una cadena vacía "". La evaluación de la política B resuelve la condición como true ("" == ""). La política forbid coincide y se rechaza la transacción.


Validación previa a la evaluación (puerta de falla rápida)

El Policy Engine aplica una validación de datos estricta. Antes de que se pase una carga útil a Cedar para la evaluación de políticas, el analizador subyacente valida la estructura de la transacción, la codificación RLP y la integridad criptográfica.

Situación 11: Cargas útiles de transacciones con formato incorrecto y no válidas

  • Contexto: Un cliente envía una secuencia de bytes con formato incorrecto, una carga útil con una estructura no válida o una transacción a la que le faltan campos criptográficos obligatorios (p.ej., una transacción de EVM con una estructura de RLP no válida o sin parámetros de gas).
  • Resultado: gRPC InvalidArgument
  • Motivo: El analizador de transacciones interno detecta la entrada no válida en la capa de API Gateway. La operación falla de inmediato, devuelve un error gRPC InvalidArgument al cliente y se omite por completo la evaluación del motor de políticas de Cedar.