Nesta página, descrevemos como o Policy Engine de computação multipartidária (MPC) avalia as políticas de transação escritas na linguagem de política Cedar, lida com cenários de várias blockchains e resolve campos de metadados opcionais ou omitidos.
Princípios básicos de avaliação
O Policy Engine usa a linguagem de política Cedar para autorizar operações de assinatura criptográfica. O mecanismo avalia as políticas de forma determinista usando três axiomas fundamentais:
- Negação padrão: todas as operações são negadas implicitamente. Para que uma operação seja permitida, ela precisa corresponder a pelo menos uma política
permitativa. Se nenhuma políticapermitcorrespondente for encontrada, a decisão final seráDENY. - Proibição explícita: uma política
forbidfunciona como uma substituição absoluta. Se uma operação corresponder a qualquer políticaforbidativa, a decisão será resolvida imediatamente comoDENY, independentemente de qualquer políticapermitcorrespondente que, de outra forma, permitiria a operação. - Campos ausentes significam apenas "Nenhuma correspondência" (pular): se uma regra procurar um campo que não está presente no payload da transação (como um campo opcional que foi deixado de fora), o Cedar não falhará. Ela trata essa regra específica como "sem correspondência" (avaliada como falsa) e passa para a próxima regra.
Matriz de avaliação lógica
A tabela a seguir demonstra como o Policy Engine avalia as combinações de regras.
Para todos os cenários, considere:
- O autor da chamada da transação (representado como o principal nas políticas do Cedar) é Alice (
User::"alice"). Na computação multipartidária, um principal representa a persona ou identidade que solicita autorização para uma operação de assinatura criptográfica (como um signatário humano, um cliente de serviço automatizado ou uma conta de sistema de back-end). - A transação está transferindo exatamente 1 ETH (representado como 1.000.000.000 de unidades de nanocoin escalonadas em
context.transaction.spend_amount_scaled).
| Cenário | Políticas ativas | Resultado | Motivo |
|---|---|---|---|
| Cenário 1: estado vazio | Nenhuma política ativa. | DENY |
Por padrão, todas as operações são bloqueadas, a menos que sejam explicitamente permitidas por uma política permit correspondente. |
| Cenário 2: correspondência de uma única permissão |
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 10000000000 }; Permite até 10 ETH |
PERMIT |
Os parâmetros da transação atendem à condição da política. Como não há políticas forbid conflitantes, a solicitação é permitida. |
| Cenário 3: incompatibilidade de uma única permissão |
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 500000000 }; Permite até 0,5 ETH |
DENY |
O valor da transferência (1 ETH) excede o limite da política. Como nenhuma regra permit correspondente é atendida, a negação padrão bloqueia a transação. |
| Cenário 4: várias políticas de permissão |
Política A: permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 500000000 }; Permite até 0,5 ETH Política B: permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 5000000000 }; Permite até 5 ETH |
PERMIT |
Embora a Política A não corresponda, a Política B corresponde. Você só precisa de uma política de permit correspondente para permitir a transação. |
| Cenário 5: conflito de permissão e proibição |
Política A (permitir): permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled < 5000000000 }; Permite até 5 ETH Política B (proibir): forbid( principal == User::"alice", action, resource ) when { context.transaction.recipient == "0xBlockedAddress" }; Presume que o destino é |
DENY |
A transferência é enviada para 0xBlockedAddress. Mesmo que a Política A permita o valor da transação, o destino corresponde aos critérios da Política B. A regra explícita forbid substitui a Política A e bloqueia a transação. |
| Cenário 6: política de proibição sem correspondência |
As mesmas políticas do cenário anterior |
PERMIT |
A transferência é enviada para um endereço seguro (por exemplo, 0xSafeAddress). A Política A corresponde, mas a Política B não, porque o destino não é 0xBlockedAddress. Na ausência de uma regra de proibição correspondente, a regra de permissão é aplicada. |
Cenários de várias cadeias e campos opcionais
Embora a matriz anterior demonstre a precedência lógica principal das regras permitidas e proibidas, os cenários a seguir ilustram como o Policy Engine avalia as regras em um ambiente de várias cadeias: especificamente ao executar em campos opcionais ou diferentes esquemas de rede de blockchain.
Observação:Normalização de dados de valor zero Para evitar erros de avaliação inesperados e garantir a previsibilidade da política, a camada de análise do Policy Engine normaliza os campos de string e byte não preenchidos no contexto de avaliação para os valores zero específicos do tipo (como uma string vazia
""ou uma matriz de bytes vazia) em vez de omiti-los.Esse comportamento permite que você elabore políticas explícitas direcionadas a campos não preenchidos sem correr o risco de erros de avaliação do Cedar. No entanto, acessar campos que não estão definidos no esquema de um blockchain (como
gas_limitsomente para EVM em uma transação do Bitcoin ououtputssomente para Bitcoin em uma transação do EVM) vai resultar em um erro de avaliação do Cedar nessa política específica, fazendo com que ela seja avaliada comofalse(sem correspondência) e falhe com segurança.
Cenário 7: avaliação de políticas entre cadeias e atributos de esquema não mapeados
Contexto:um autor de chamada envia uma transação de Bitcoin. No entanto, o conjunto de políticas ativo contém uma política específica do Ethereum:
permit( principal == User::"alice", action, resource ) when { context.transaction.schema == "ethereum.transaction.v2" && context.transaction.gas_limit < 100000 };Resultado:
DENYMotivo:os atributos de intenção universal (como
spend_amount_scaled,recipientemax_fee_atomic) são avaliados de forma consistente nas transações de Ethereum e Bitcoin. Quando uma política faz referência a atributos específicos da rede que não existem no esquema da transação enviada (comogas_limitem uma transação de Bitcoin), o Cedar trata o atributo não correspondente como uma falha de avaliação, resolvendo essa política específica comofalse(sem correspondência) sem interromper o mecanismo. Como nenhuma outra política ativa depermitcorresponde à transação de Bitcoin, a operação é negada por padrão.
Cenário 8: campo opcional ausente em uma política permit
Contexto:um autor de chamada envia uma transferência padrão de ETH (que não usa contratos inteligentes). O conjunto de políticas ativo contém uma regra que verifica as interações do contrato:
permit( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "0x1111111111111111111111111111111111111111" };Resultado:
DENYMotivo:para uma transferência padrão de ETH, o
asset_contract_addressopcional não é preenchido. O analisador normaliza isso para a string vazia de valor zero""no contexto de avaliação. A avaliação da comparação"" == "0x1111..."retornafalse(sem correspondência) em vez de gerar um erro. Como nenhuma outra política permite a transferência, a operação é negada por padrão.
Cenário 9: campo opcional ausente em uma política forbid
Contexto:um autor de chamada envia uma transferência padrão de 10 ETH. O conjunto de políticas consiste em:
Política A (permitir):
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled <= 100000000000 };Política B (proibir):
forbid( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "0xBannedContract" };
Resultado:
PERMITMotivo:a Política A corresponde porque 10 ETH está abaixo do limite. A política B verifica se o endereço do contrato corresponde a um endereço banido. Devido à normalização de valor zero, o endereço de contrato não preenchido é resolvido como
"". A avaliação da comparação"" == "0xBannedContract"retornafalse. Como a política de proibição não corresponde, mas a de permissão sim, a transação é permitida.
Cenário 10: verificação explícita de campos vazios ou ausentes
Contexto:um autor de chamada envia uma transferência padrão de ETH (que não é enviada para um contrato inteligente). O conjunto de políticas consiste em:
Política A (permitir):
permit( principal == User::"alice", action, resource ) when { context.transaction.spend_amount_scaled <= 1000000000000 };Política B (proibir):
forbid( principal == User::"alice", action, resource ) when { context.transaction.asset_contract_address == "" };
Resultado:
DENYMotivo:devido à normalização do analisador, o
asset_contract_addressausente é apresentado no contexto de avaliação como uma string vazia"". A avaliação da Política B resolve a condição comotrue("" == ""). A políticaforbidcorresponde, e a transação é negada.
Validação pré-avaliação (Fail-Fast Gate)
O Policy Engine aplica uma validação de dados rigorosa. Antes que um payload seja transmitido ao Cedar para avaliação de políticas, o analisador subjacente valida a estrutura da transação, a codificação RLP e a integridade criptográfica.
Cenário 11: payloads de transação inválidos e malformados
- Contexto:um cliente envia uma sequência de bytes malformada, um payload com estrutura inválida ou uma transação sem campos criptográficos obrigatórios (por exemplo, uma transação de EVM com uma estrutura RLP inválida ou sem parâmetros de gás).
- Resultado:
gRPC InvalidArgument - Motivo:o analisador de transações interno detecta a entrada inválida na camada do gateway de API. A operação falha imediatamente, retornando um erro
gRPC InvalidArgumentao cliente, e a avaliação pelo Cedar Policy Engine é totalmente ignorada.