Valutazione delle norme con Cedar

Questa pagina descrive in che modo il Policy Engine di calcolo multipartitico (MPC) valuta le policy delle transazioni scritte nel linguaggio delle policy Cedar, gestisce gli scenari cross-chain e risolve i campi dei metadati facoltativi o omessi.

Principi di valutazione fondamentali

Il Policy Engine utilizza il linguaggio delle policy Cedar per autorizzare le operazioni di firma crittografica. Il motore valuta le policy in modo deterministico utilizzando tre assiomi fondamentali:

  1. Rifiuto predefinito: tutte le operazioni vengono rifiutate in modo implicito. Affinché un'operazione sia consentita, deve corrispondere ad almeno una policy permit attiva. Se non viene trovata alcuna policy permit corrispondente, la decisione finale è DENY.
  2. Divieto esplicito: una policy forbid agisce come un override assoluto. Se un'operazione corrisponde a una policy forbid attiva, la decisione viene immediatamente risolta in DENY, indipendentemente dalle policy permit corrispondenti che altrimenti consentirebbero l'operazione.
  3. Missing Fields Just Mean "No Match" (Skip) (I campi mancanti significano semplicemente "Nessuna corrispondenza" (Salta)): se una regola cerca un campo che non è presente nel payload della transazione (ad esempio un campo facoltativo che è stato omesso), Cedar non si arresta in modo anomalo. Considera la regola specifica come "nessuna corrispondenza" (restituisce false) e passa alla regola successiva.

Matrice di valutazione logica

La tabella seguente mostra come il Policy Engine valuta le combinazioni di regole.

Per tutti gli scenari, supponiamo che:

  • Il chiamante della transazione (rappresentato come entità nelle policy Cedar) è Alice (User::"alice"). Nel calcolo multipartitico, un'entità rappresenta la persona o l'identità che richiede l'autorizzazione per un'operazione di firma crittografica (ad esempio un firmatario umano, un client di servizio automatizzato o un account di sistema di backend).
  • La transazione trasferisce esattamente 1 ETH (rappresentato come 1.000.000.000 di unità nanocoin scalate in context.transaction.spend_amount_scaled).
Scenario Policy attive Risultato Motivo
Scenario 1: stato vuoto Nessuna policy attiva. DENY Per impostazione predefinita, tutte le operazioni sono bloccate, a meno che non siano esplicitamente consentite da una policy permit corrispondente.
Scenario 2: corrispondenza con un singolo permesso
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 10000000000
};

Consente fino a 10 ETH

PERMIT I parametri della transazione soddisfano la condizione della policy. Poiché non esistono policy forbid in conflitto, la richiesta è consentita.
Scenario 3: mancata corrispondenza di un singolo permesso
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 500000000
};

Consente fino a 0,5 ETH

DENY L'importo del trasferimento (1 ETH) supera il limite della policy. Poiché non vengono soddisfatte regole permit corrispondenti, il blocco predefinito blocca la transazione.
Scenario 4: più policy di autorizzazione

Policy A:

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

Consente fino a 0,5 ETH

Policy B:

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

Consente fino a 5 ETH

PERMIT Sebbene la policy A non corrisponda, la policy B corrisponde. Per consentire la transazione, è sufficiente una sola policy permit corrispondente.
Scenario 5: conflitto tra autorizzazione e divieto

Policy A (consenti):

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

Consente fino a 5 ETH

Policy B (forbid):

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

Presuppone che la destinazione sia 0xBlockedAddress

DENY Il trasferimento viene inviato a 0xBlockedAddress. Anche se la Policy A consente l'importo della transazione, la destinazione corrisponde ai criteri della Policy B. La regola forbid esplicita esegue l'override della Policy A e blocca la transazione.
Scenario 6: policy di divieto non corrispondente

Stesse policy dello scenario precedente

PERMIT Il trasferimento viene inviato a un indirizzo sicuro (ad es. 0xSafeAddress). La policy A corrisponde correttamente, mentre la policy B non corrisponde perché la destinazione non è 0xBlockedAddress. In assenza di una regola di divieto corrispondente, viene applicata la regola di autorizzazione.

Scenari con più catene e campi facoltativi

Sebbene la matrice precedente mostri la precedenza logica di base delle regole consentite e vietate, i seguenti scenari illustrano come il Policy Engine valuta le regole in un ambiente multi-chain, in particolare quando vengono eseguite su campi facoltativi o schemi di rete blockchain diversi.

Nota: Normalizzazione dei dati con valore zero Per evitare errori di valutazione imprevisti e garantire la prevedibilità delle policy, il livello di analisi del Policy Engine normalizza i campi di stringhe e byte non compilati nel contesto di valutazione ai valori zero specifici del tipo (ad esempio una stringa vuota "" o un array di byte vuoto) anziché ometterli.

Questo comportamento ti consente di creare bozze di policy esplicite che hanno come target campi non compilati senza rischiare errori di valutazione di Cedar. Tuttavia, l'accesso a campi completamente non definiti nello schema di una blockchain (come gas_limit solo EVM in una transazione Bitcoin o outputs solo Bitcoin in una transazione EVM) comporterà un errore di valutazione Cedar su quella specifica policy, che verrà valutata come false (nessuna corrispondenza) e non verrà applicata in modo sicuro.

Scenario 7: valutazione delle policy cross-chain e attributi dello schema non mappati

  • Contesto: un chiamante invia una transazione in Bitcoin. Tuttavia, il set di policy attivo contiene una policy specifica per Ethereum:

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

  • Motivo: gli attributi di intent universali (come spend_amount_scaled, recipient e max_fee_atomic) vengono valutati in modo coerente sia per le transazioni Ethereum che per quelle Bitcoin. Quando una policy fa riferimento ad attributi specifici della catena che non esistono nello schema della transazione inviata (ad esempio gas_limit in una transazione Bitcoin), Cedar considera l'attributo non corrispondente come un errore di valutazione, risolvendo la policy specifica in false (nessuna corrispondenza) senza arrestare il motore. Poiché nessun'altra policy permit attiva corrisponde alla transazione Bitcoin, l'operazione viene negata per impostazione predefinita.

Scenario 8: campo facoltativo mancante in una policy permit

  • Contesto: un chiamante invia un trasferimento ETH standard (che non utilizza smart contract). Il set di policy attivo contiene una regola che controlla le interazioni con i contratti:

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

  • Motivo: per un trasferimento ETH standard, il campo facoltativo asset_contract_address non è compilato. Il parser normalizza questo valore nella stringa vuota con valore zero "" nel contesto di valutazione. La valutazione del confronto "" == "0x1111..." restituisce false (nessuna corrispondenza) anziché generare un errore. Poiché nessun'altra policy consente il trasferimento, l'operazione viene negata per impostazione predefinita.

Scenario 9: campo facoltativo mancante in una policy forbid

  • Contesto: un chiamante invia un trasferimento ETH standard di 10 ETH. Il set di policy è composto da:

    • Policy A (consenti):

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

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

  • Motivo: la policy A viene applicata correttamente perché 10 ETH è inferiore al limite. La policy B controlla se l'indirizzo del contratto corrisponde a un indirizzo vietato. A causa della normalizzazione del valore zero, l'indirizzo del contratto non compilato viene risolto in "". La valutazione del confronto "" == "0xBannedContract" restituisce false. Poiché la policy di divieto non corrisponde e la policy di autorizzazione sì, la transazione è consentita.

Scenario 10: controllo esplicito dei campi vuoti o mancanti

  • Contesto: un chiamante invia un trasferimento ETH standard (che non viene inviato a uno smart contract). Il set di policy è composto da:

    • Policy A (consenti):

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

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

  • Motivo: a causa della normalizzazione del parser, l'elemento asset_contract_address mancante viene presentato nel contesto di valutazione come una stringa vuota "". La valutazione della policy B risolve la condizione in true ("" == ""). La policy forbid corrisponde e la transazione viene negata.


Convalida pre-valutazione (Fail-Fast Gate)

Il Policy Engine applica una convalida dei dati rigorosa. Prima che un payload venga passato a Cedar per la valutazione delle policy, l'analizzatore sottostante convalida la struttura della transazione, la codifica RLP e l'integrità crittografica.

Scenario 11: payload di transazioni non validi e con formato non corretto

  • Contesto: un client invia una sequenza di byte non corretta, un payload con una struttura non valida o una transazione priva di campi crittografici obbligatori (ad es. una transazione EVM con una struttura RLP non valida o parametri gas mancanti).
  • Risultato: gRPC InvalidArgument
  • Motivo: l'analizzatore sintattico delle transazioni interne rileva l'input non valido a livello di API Gateway. L'operazione non va a buon fine immediatamente, restituendo un errore gRPC InvalidArgument al client, e la valutazione da parte del Cedar Policy Engine viene ignorata completamente.