Richtlinienauswertung mit Cedar

Auf dieser Seite wird beschrieben, wie die Multi-Party Computation (MPC) Policy Engine Transaktionsrichtlinien auswertet, die in der Cedar-Richtliniensprache geschrieben sind, wie sie kettenübergreifende Szenarien verarbeitet und wie sie optionale oder weggelassene Metadatenfelder auflöst.

Grundprinzipien der Bewertung

Die Policy Engine verwendet die Cedar Policy Language, um kryptografische Signaturvorgänge zu autorisieren. Die Engine wertet Richtlinien deterministisch anhand von drei grundlegenden Axiomen aus:

  1. Standardmäßig ablehnen: Alle Vorgänge werden implizit abgelehnt. Damit ein Vorgang zulässig ist, muss er mit mindestens einer aktiven permit-Richtlinie übereinstimmen. Wenn keine übereinstimmende permit-Richtlinie gefunden wird, lautet die endgültige Entscheidung DENY.
  2. Explizites Verbot: Eine forbid-Richtlinie fungiert als absolute Überschreibung. Wenn ein Vorgang mit einer aktiven forbid-Richtlinie übereinstimmt, wird die Entscheidung sofort auf DENY festgelegt, unabhängig von übereinstimmenden permit-Richtlinien, die den Vorgang andernfalls zulassen würden.
  3. Fehlende Felder bedeuten einfach „Keine Übereinstimmung“ (Überspringen): Wenn eine Regel nach einem Feld sucht, das in der Transaktionsnutzlast nicht vorhanden ist (z. B. ein optionales Feld, das weggelassen wurde), stürzt Cedar nicht ab. Die jeweilige Regel wird als „keine Übereinstimmung“ behandelt (als „falsch“ ausgewertet) und die nächste Regel wird geprüft.

Logische Bewertungsmatrix

In der folgenden Tabelle wird gezeigt, wie die Policy Engine Regelkombinationen auswertet.

Für alle Szenarien gilt:

  • Der Transaktionsaufrufer (in Cedar-Richtlinien als Hauptkonto dargestellt) ist Alice (User::"alice"). Bei der Multi-Party Computation stellt ein Hauptkonto die Persona oder Identität dar, die eine Autorisierung für einen kryptografischen Signiervorgang anfordert (z. B. ein menschlicher Signierer, ein automatisierter Dienstclient oder ein Backend-Systemkonto).
  • Mit der Transaktion wird genau 1 ETH übertragen (dargestellt als 1.000.000.000 skalierte Nanocoin-Einheiten in context.transaction.spend_amount_scaled).
Szenario Aktive Richtlinien Ergebnis Grund
Szenario 1: Leerer Zustand Keine aktiven Richtlinien. DENY Standardmäßig werden alle Vorgänge blockiert, sofern sie nicht explizit durch eine entsprechende permit-Richtlinie zugelassen werden.
Szenario 2: Einzelne Genehmigung stimmt überein
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 10000000000
};

Bis zu 10 ETH zulässig

PERMIT Die Transaktionsparameter erfüllen die Richtlinienbedingung. Da es keine widersprüchlichen forbid-Richtlinien gibt, ist die Anfrage zulässig.
Szenario 3: Abweichung bei einer einzelnen Genehmigung
permit(
  principal == User::"alice",
  action,
  resource
)
when {
  context.transaction.spend_amount_scaled < 500000000
};

Erlaubt bis zu 0,5 ETH

DENY Der Überweisungsbetrag (1 ETH) überschreitet das Richtlinienlimit. Da keine übereinstimmenden permit-Regeln erfüllt sind, wird die Transaktion durch die Standardablehnung blockiert.
Szenario 4: Mehrere Genehmigungsrichtlinien

Richtlinie A:

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

Erlaubt bis zu 0,5 ETH

Richtlinie B:

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

Bis zu 5 ETH zulässig

PERMIT Richtlinie A stimmt zwar nicht überein, aber Richtlinie B. Sie benötigen nur eine übereinstimmende permit-Richtlinie, um die Transaktion zuzulassen.
Szenario 5: Konflikt zwischen „Zulassen“ und „Verbieten“

Richtlinie A (Zulassen):

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

Bis zu 5 ETH zulässig

Richtlinie B (verbieten):

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

Nimmt an, dass das Ziel 0xBlockedAddress ist

DENY Die Überweisung wird an 0xBlockedAddress gesendet. Obwohl Richtlinie A den Transaktionsbetrag zulässt, entspricht das Ziel den Kriterien für Richtlinie B. Die explizite forbid-Regel überschreibt Richtlinie A und blockiert die Transaktion.
Szenario 6: Nicht übereinstimmende Verbotsrichtlinie

Dieselben Richtlinien wie im vorherigen Szenario

PERMIT Die Übertragung wird an eine sichere Adresse gesendet (z.B. 0xSafeAddress). Richtlinie A stimmt überein, Richtlinie B jedoch nicht, da das Ziel nicht 0xBlockedAddress ist. Wenn keine übereinstimmende Verbotsregel vorhanden ist, wird die Zulassungsregel angewendet.

Szenarien mit mehreren Ketten und optionalen Feldern

Die obige Matrix zeigt die grundlegende logische Priorität von zulässigen und verbotenen Regeln. Die folgenden Szenarien veranschaulichen, wie die Policy Engine Regeln in einer Umgebung mit mehreren Chains auswertet, insbesondere bei der Ausführung für optionale Felder oder verschiedene Blockchain-Netzwerkschemas.

Hinweis: Normalisierung von Nullwerten Um unerwartete Auswertungsfehler zu vermeiden und die Vorhersehbarkeit von Richtlinien zu gewährleisten, normalisiert die Parsing-Ebene der Policy Engine nicht ausgefüllte String- und Bytefelder im Auswertungskontext auf ihre typspezifischen Nullwerte (z. B. einen leeren String "" oder ein leeres Byte-Array), anstatt sie wegzulassen.

So können Sie explizite Richtlinien für nicht ausgefüllte Felder erstellen, ohne Cedar-Bewertungsfehler zu riskieren. Wenn Sie jedoch auf Felder zugreifen, die im Schema einer Blockchain überhaupt nicht definiert sind (z. B. das EVM-spezifische Feld gas_limit in einer Bitcoin-Transaktion oder das Bitcoin-spezifische Feld outputs in einer EVM-Transaktion), führt dies zu einem Cedar-Auswertungsfehler für diese Richtlinie. Die Richtlinie wird dann als false (keine Übereinstimmung) ausgewertet und sicher abgelehnt.

Szenario 7: Kettenübergreifende Richtlinienbewertung und nicht zugeordnete Schemaattribute

  • Kontext: Ein Aufrufer reicht eine Bitcoin-Transaktion ein. Das aktive Richtlinienset enthält jedoch eine Ethereum-spezifische Richtlinie:

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

  • Grund: Universelle Intent-Attribute (wie spend_amount_scaled, recipient und max_fee_atomic) werden sowohl für Ethereum- als auch für Bitcoin-Transaktionen einheitlich ausgewertet. Wenn eine Richtlinie auf kettenspezifische Attribute verweist, die im Schema der gesendeten Transaktion nicht vorhanden sind (z. B. gas_limit bei einer Bitcoin-Transaktion), behandelt Cedar das nicht übereinstimmende Attribut als Bewertungsfehler und löst diese Richtlinie zu false (keine Übereinstimmung) auf, ohne die Engine anzuhalten. Da keine andere aktive permit-Richtlinie mit der Bitcoin-Transaktion übereinstimmt, wird der Vorgang standardmäßig abgelehnt.

Szenario 8: Fehlendes optionales Feld in einer permit-Richtlinie

  • Kontext: Ein Aufrufer sendet eine Standard-ETH-Übertragung (ohne Smart Contracts). Der aktive Richtliniensatz enthält eine Regel, die Vertragsinteraktionen prüft:

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

  • Grund: Bei einer Standard-ETH-Übertragung ist das optionale Feld asset_contract_address nicht ausgefüllt. Der Parser normalisiert dies im Auswertungskontext auf den Nullwert-Leerstring "". Bei der Auswertung des Vergleichs "" == "0x1111..." wird false (keine Übereinstimmung) zurückgegeben, anstatt einen Fehler auszugeben. Da keine andere Richtlinie die Übertragung zulässt, wird der Vorgang standardmäßig abgelehnt.

Szenario 9: Fehlendes optionales Feld in einer forbid-Richtlinie

  • Kontext: Ein Aufrufer sendet eine Standard-ETH-Übertragung von 10 ETH. Die Richtliniengruppe besteht aus:

    • Richtlinie A (Zulassen):

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

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

  • Grund: Richtlinie A stimmt überein, da 10 ETH unter dem Limit liegen. Richtlinie B prüft, ob die Vertragsadresse mit einer gesperrten Adresse übereinstimmt. Aufgrund der Nullwertnormalisierung wird die nicht ausgefüllte Vertragsadresse zu "" aufgelöst. Die Auswertung des Vergleichs "" == "0xBannedContract" ergibt false. Da die Verbotsrichtlinie nicht übereinstimmt, die Zulassungsrichtlinie aber schon, ist die Transaktion zulässig.

Szenario 10: Explizite Prüfung leerer oder fehlender Felder

  • Kontext: Ein Aufrufer sendet eine Standard-ETH-Übertragung, die nicht an einen Smart Contract gesendet wird. Die Richtliniengruppe besteht aus:

    • Richtlinie A (Zulassen):

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

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

  • Grund: Aufgrund der Parser-Normalisierung wird der fehlende asset_contract_address im Auswertungskontext als leerer String "" dargestellt. Bei der Auswertung von Richtlinie B wird die Bedingung zu true ("" == "") aufgelöst. Die Richtlinie forbid stimmt überein und die Transaktion wird abgelehnt.


Validierung vor der Bewertung (Fail-Fast-Gate)

Die Policy Engine erzwingt eine strenge Datenvalidierung. Bevor eine Nutzlast zur Richtlinienbewertung an Cedar übergeben wird, validiert der zugrunde liegende Parser die Transaktionsstruktur, die RLP-Codierung und die kryptografische Integrität.

Szenario 11: Fehlerhafte und ungültige Transaktionsnutzlasten

  • Kontext: Ein Client sendet eine fehlerhafte Bytesequenz, eine Nutzlast mit ungültiger Struktur oder eine Transaktion, bei der obligatorische kryptografische Felder fehlen (z.B. eine EVM-Transaktion mit einer ungültigen RLP-Struktur oder fehlenden Gasparametern).
  • Ergebnis: gRPC InvalidArgument
  • Grund: Der interne Transaktionsparser erkennt die ungültige Eingabe auf der API-Gateway-Ebene. Der Vorgang schlägt sofort fehl, der Client erhält den Fehler gRPC InvalidArgument und die Prüfung durch die Cedar Policy Engine wird vollständig umgangen.