Cedar-Regeln schreiben

Auf dieser Seite wird beschrieben, wie Sie Cedar-Richtlinienregeln erstellen, um Transaktionen in der Policy Engine für Multi-Party Computation (MPC) zu validieren.

Die Policy Engine decodiert eingehende Transaktionsnutzlasten in einer sicheren vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) und projiziert die Transaktionsabsichtsattribute auf den Cedar-Bewertungskontext.

Cedar-Regelstruktur

Wenn Sie Cedar-Regeln für die Policy Engine schreiben, geben Sie eine Regel mit einer verschachtelten Gruppe von Bedingungen an:

  • Hauptkonto: Die logische Identität des Transaktionsanforderers (des Initiators der Transaktion) im Multi-Party Compute-Arbeitsbereich (z. B. User::"alice") und nicht die Google Cloud IAM-Identität (Nutzer oder Dienstkonto), die die API aufruft.
  • Aktion: Die angeforderte kryptografische Aktion (z. B. Action::"sign_transaction").
  • Ressource: Das Ziel-Asset oder die Vorgangsklasse, für die der Vorgang ausgeführt wird (z. B. Resource::"mpc_operation").
  • Kontext: Die geparsten Transaktionsmetadaten und ‑parameter (zugänglich unter context.transaction).

Referenz zum Ethereum-Transaktionsschema

Das protokollunabhängige Framework ermöglicht es, die Schemaprüfung in Regeln wegzulassen, damit sie in verschiedenen Blockchain-Netzwerken wiederverwendet werden können. Wenn Sie eine Regel explizit auf Ethereum-Transaktionsnutzlasten beschränken möchten, prüfen Sie Folgendes: context.transaction.schema == "ethereum.transaction.v2".

Die folgenden Attribute werden im context.transaction-Eintrag unterstützt:

Attribut Typ Beschreibung
schema String Das Formatschema. Bei Ethereum-Transaktionen ist dies immer "ethereum.transaction.v2".
operation String Der Transaktionsvorgangstyp. Unterstützte Werte:
  • "NATIVE_TRANSFER": Eine direkte Übertragung der Währung der Hauptkette (z. B. ETH).
  • "TOKEN_TRANSFER": Eine ERC-20-Tokenübertragung (z. B. USDC, USDT, DAI).
  • "TOKEN_APPROVE": Eine ERC-20-Tokengenehmigung, mit der ein Vertrag Tokens ausgeben kann.
  • "CONTRACT_CALL": Eine allgemeine Smart-Contract-Interaktion (z. B. Staking oder Swapping).
chain_id String Die ID des Ziel-Blockchain-Netzwerks (z. B. "1" für Ethereum Mainnet oder "11155111" für Sepolia Testnet).
asset_symbol String Das Tickersymbol des übertragenen Tokens (z. B. "ETH", "USDC", "DAI" oder "WBTC"). Bei nicht gelisteten Tokens wird "UNKNOWN" zurückgegeben.
asset_contract_address String Die Smart-Contract-Adresse des ERC-20-Tokens (im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung). Bei Standard-ETH-Übertragungen wird dies in einen leeren String ("") aufgelöst.
recipient String Die Zieladresse des Empfängers (im EIP-55-Prüfsummenformat mit Groß- und Kleinschreibung). Bei Tokengenehmigungen ist dies die Adresse des Ausgebenden.
spend_amount_scaled Lang Der Token-Übertragungsbetrag wird auf eine feste Genauigkeit von 9 Dezimalstellen (Nanocoin-Format) normalisiert. Dadurch müssen beim Schreiben von Regeln keine unterschiedlichen Token-Dezimalstellen (z. B. 6, 8 oder 18) mehr berücksichtigt werden.

Berechnung: Multiplizieren Sie den menschenlesbaren Asset-Betrag (z. B. 1,5 ETH oder 5.000 USDC) mit 1.000.000.000 (109), um den Wert für Ihre Regel zu erhalten:
  • 0.1 ETH → 100000000 (0,1 × 109)
  • 1.0 eines beliebigen Assets → 1000000000 (1,0 × 109)
  • 5,000 USDC → 5000000000000 (5.000 × 109)
spend_amount_dust Lang Der verbleibende Rest des Transaktionsbetrags, der unter den Schwellenwert für die Genauigkeit von 9 Dezimalstellen fällt. Bei Assets mit mehr als 9 Dezimalstellen (z. B. ETH mit 18 Dezimalstellen) enthält dieses Feld den unskalierten Sub-Gwei-Wert (die verbleibenden Wei). Bei Assets mit 9 oder weniger Dezimalstellen (z. B. USDC oder WBTC) ist dies immer 0.
max_fee_atomic Lang Die maximale Gesamttransaktionsgebühr (skaliert um 109, was Gwei entspricht).
gas_limit Lang Die maximale Menge an Gas, die für die Transaktionsausführung zugewiesen wird.
destination_type String Die Klassifizierung der Empfängeradresse. Unterstützte Werte: "EOA" (Standard-Nutzer-Wallet), "CONTRACT" (Smart Contract) oder "INTERNAL_TREASURY" (interner Vault).
temporal_validity Lang Die Nonce des Transaktionskontos (wird verwendet, um Replay-Angriffe auf Transaktionen zu verhindern).

Referenz zum Bitcoin-Transaktionsschema

Wenn Sie eine Regel explizit auf Bitcoin BIP 174 PSBT-Transaktionsnutzlasten beschränken möchten, prüfen Sie Folgendes: context.transaction.schema == "bitcoin.transaction.v2".

Die folgenden Attribute werden im context.transaction-Eintrag unterstützt:

Attribut Typ Beschreibung
schema String Das Formatschema. Bei Bitcoin-Transaktionen ist dies immer "bitcoin.transaction.v2".
operation String Der Transaktionsvorgangstyp. Unterstützte Werte:
  • "NATIVE_TRANSFER": Eine direkte Übertragung von Bitcoin (BTC).
  • "OP_RETURN": Eine nicht auszugebende Datenverankerung / Null-Datenausgabe.
chain_id String Der menschenlesbare Teil (HRP) des Bech32-Zielnetzwerks: "bc" (Bitcoin-Mainnet), "tb" (Testnet / Testnet4) oder "bcrt" (Regtest).
asset_symbol String Das Tickersymbol des Assets: "BTC".
recipient String Die primäre Zieladresse. Bei OP_RETURN-Transaktionen ist dies "unaddressable". Bei internen Konsolidierungs-Sweeps (100% Wechsel) wird dies in die erste Wechseladresse aufgelöst.
spend_amount_scaled Lang Der Nettobetrag der ausgehenden Überweisung, normalisiert auf eine feste Genauigkeit von 9 Dezimalstellen (10-9-Einheiten). Da 1 Satoshi 10 Nanocoin-Einheiten entspricht (1 Sat = 10 Einheiten, 1 BTC = 109 Einheiten), werden interne Wechselgeldbeträge ausgeschlossen. Bei internen Sweeps / Transaktionen mit 100% Wechselgeld wird hier 0 ausgegeben.
max_fee_atomic Lang Die berechnete Obergrenze für die Miner-Gebühr, normalisiert auf eine Genauigkeit von 9 Dezimalstellen: (∑ Eingaben − ∑ Ausgaben) × 10.
destination_type String Die Klassifizierung des Empfängerskripts. Unterstützte Werte: "P2WPKH" (Native SegWit), "P2TR" (Taproot), "P2PKH" (Legacy), "P2SH" (Nested SegWit / Script Hash), "TREASURY_CHANGE" (interne Änderung) oder "".
temporal_validity Lang Das Transaktionsfeld nLockTime.
outputs Set<Record> Der normalisierte Satz aller Transaktionsausgaben: [{ address: String, amount_scaled: Long, is_change: Bool }].

Wichtige Konzepte der Bitcoin-Richtlinie

  1. Universelle 9-Dezimalstellen-Skalierung: Beträge in Bitcoin-Richtlinien verwenden eine normalisierte 9-Dezimalstellen-Nanocoin-Präzision (1 Sat = 10 Einheiten, 1 BTC = 109 Einheiten):

    Amountscaled = Satoshis × 10 = BTC × 109

    • 0.0005 BTC (50.000 Satoshis) → 500000 (50.000 × 10)
    • 0.0025 BTC (250.000 Satoshis) → 2500000 (250.000 × 10)
    • 1.0 BTC (100.000.000 Satoshis) → 1000000000 (100.000.000 × 10)
  2. Ausgabe für Wechselgeld trennen: Der Parser prüft BIP-32-Ableitungspfade (m/.../1/*) und korreliert Eingabescripts, um Ausgaben für Wechselgeld automatisch zu identifizieren. Wechselgeldbeträge sind von spend_amount_scaled ausgeschlossen, damit Richtlinien für Ausgabenlimits strikt anhand des Nettowerts der ausgehenden Überweisungen an Dritte bewertet werden.

  3. Regel für einen einzelnen Empfänger, der nicht geändert werden darf: Um mehrdeutige Routingangriffe mit mehreren Empfängern zu verhindern, werden Transaktionen mit mehreren unterschiedlichen externen Drittanbieterempfängern abgelehnt (ErrUnsupportedTx).


Beispiele für Cedar-Regeln

In den folgenden Beispielen wird gezeigt, wie Sie Zulassungslisten, Limitregeln und Replay-Grenzen mit Cedar für Ethereum- und Bitcoin-Transaktionen konfigurieren.

Ethereum-Beispiele

Die folgenden Regeln veranschaulichen gängige Richtlinienmuster für Ethereum- und ERC-20-Transaktionen.

1. Limit für direkte ETH-Übertragungen

Diese Regel erlaubt Alice, ETH auf der Base-Chain zu übertragen,und prüft,ob der skalierte Übertragungsbetrag 1,0 ETH (1.000.000.000 skalierte Gwei-Einheiten) nicht überschreitet.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.operation == "NATIVE_TRANSFER" &&
    context.transaction.asset_symbol == "ETH" &&
    context.transaction.spend_amount_scaled <= 1000000000
};

2. Regel für die Zulassungsliste für ERC-20-Tokens

Diese Regel erlaubt USDC-Token-Übertragungen bis zu 5.000 USDC. Übertragungen werden auf Empfängeradressen auf einer Zulassungsliste beschränkt. Da bei Cedar-Strings die Groß-/Kleinschreibung berücksichtigt wird, muss die Empfängeradresse dem EIP-55-Format mit Groß- und Kleinschreibung entsprechen.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.operation == "TOKEN_TRANSFER" &&
    context.transaction.asset_symbol == "USDC" &&
    context.transaction.recipient == "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" &&
    context.transaction.spend_amount_scaled <= 5000000000000
};

3. Smart Contract- und DeFi-Aufruf-Fallbacks

Diese Regel erlaubt allgemeine Vertragsinteraktionen (wie Staking oder Swapping) ohne Betragsbeschränkungen, sofern es sich nicht um Übertragungsvorgänge handelt, bei denen Vermögenswerte ausgegeben werden.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.operation == "CONTRACT_CALL"
};

4. Strikter Schutz vor Wiederholungsangriffen (Chain-ID-Grenze)

Um Replay-Angriffe zu verhindern, bei denen eine für eine Testnet-Chain signierte Nutzlast noch einmal in Produktions-Mainnets gesendet wird, können Sie Ihre Regel auf eine bestimmte Chain-ID beschränken (z.B. 11155111 für Sepolia).

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.chain_id == "11155111"
};

Bitcoin-Beispiele

Die folgenden Regeln veranschaulichen gängige Richtlinienmuster für Bitcoin-PSBT-Transaktionen.

1. Ausgabenlimit und Obergrenze für Miner-Gebühren

Diese Regel erlaubt direkte Bitcoin-Überweisungen (BTC), bei denen der Nettobetrag der ausgehenden Überweisung 0,0025 BTC (250.000 Satoshis → 2.500.000 skalierte Einheiten) und die Miner-Gebühr 10.000 Satoshis (100.000 atomare Einheiten) nicht überschreitet.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.operation == "NATIVE_TRANSFER" &&
    context.transaction.asset_symbol == "BTC" &&
    context.transaction.spend_amount_scaled <= 2500000 &&
    context.transaction.max_fee_atomic <= 100000
};

2. Zulassungsliste für SegWit- (P2WPKH) und Taproot-Adressen (P2TR)

Diese Regel beschränkt Bitcoin-Übertragungen auf eine genehmigte SegWit- oder Taproot-Zieladresse.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.schema == "bitcoin.transaction.v2" &&
    (context.transaction.destination_type == "P2WPKH" || context.transaction.destination_type == "P2TR") &&
    context.transaction.recipient == "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
};

3. UTXO-Konsolidierung und Treasury-Sweep

Diese Regel erlaubt interne UTXO-Konsolidierungen, bei denen alle Ausgaben an interne Wechseladressen (destination_type == "TREASURY_CHANGE" und spend_amount_scaled == 0) zurückgegeben werden, und begrenzt gleichzeitig die Konsolidierungsgebühr.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.schema == "bitcoin.transaction.v2" &&
    context.transaction.destination_type == "TREASURY_CHANGE" &&
    context.transaction.spend_amount_scaled == 0 &&
    context.transaction.max_fee_atomic <= 50000
};

4. Prüfung des Ausgabesatzes

Mit dieser Regel wird geprüft, ob der Transaktionsausgabesatz eine bestimmte Zielausgabe und einen bestimmten Betrag enthält.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.outputs.contains({
        address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
        amount_scaled: 500000,
        is_change: false
    })
};

5. Netzwerkbereich (Mainnet im Vergleich zu Testnet)

Diese Regel beschränkt die Autorisierung auf Bitcoin Testnet-Transaktionen (tb) und verhindert die Ausführung im Bitcoin Mainnet (bc).

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.schema == "bitcoin.transaction.v2" &&
    context.transaction.chain_id == "tb"
};

6. OP_RETURN-Datenverankerung

Diese Regel erlaubt nicht auszugebende OP_RETURN-Datenverankerungstransaktionen (spend_amount_scaled == 0 und recipient == "unaddressable") und erzwingt eine strenge Gebührenobergrenze.

permit (
    principal == User::"alice",
    action == Action::"sign_transaction",
    resource == Resource::"mpc_operation"
)
when {
    context.transaction.operation == "OP_RETURN" &&
    context.transaction.recipient == "unaddressable" &&
    context.transaction.spend_amount_scaled == 0 &&
    context.transaction.max_fee_atomic <= 10000
};

Sicherheitsmaßnahmen für Parser

Um Transaktionsvorgänge in Produktionsumgebungen zu schützen, parst die Policy Engine Nutzlasten strikt und lehnt ungültige Strukturen auf der Gateway-Ebene ab, bevor Cedar-Regeln ausgewertet werden:

  • Erzwingung der Basiswährung mit dem Wert null: Der Parser lehnt Ethereum-Token-Übertragungsvorgänge (TOKEN_TRANSFER) explizit ab, bei denen auch versucht wird, Basisübertragungs-Assets mit einem Wert ungleich null zu bündeln. So wird verhindert, dass schädliche Nutzlasten Standard-Basis-Asset-Werte übertragen, während die Transaktion als Standard-Token-Übertragung dargestellt wird.
  • UTXO- und Witness-Verifizierung: Bei Bitcoin-PSBT-Transaktionen prüft der Parser, ob alle Eingaben gültige witness_utxo-Daten liefern. So wird verhindert, dass die Gebührenberechnung manipuliert oder eine nicht verifizierte Signatur verwendet wird.
  • Überprüfung des Skripts für die Wechselgeldausgabe: Interne Wechselgeldausgaben müssen mit einem Eingabeskript-Pubkey oder einem bekannten BIP-32-Wechselgeldpfad (m/.../1/*) übereinstimmen. Nutzlasten, die versuchen, Wechselgeldausgaben an Adressen von Drittanbietern zu fälschen, schlagen fehl.
  • Erzwingung eines einzelnen externen Empfängers:Bitcoin-Nutzlasten mit mehreren externen Zieladressen, die keine Wechselgeldadressen sind, werden abgelehnt (ErrUnsupportedTx), um eine mehrdeutige Autorisierung von Richtlinien für mehrere Empfänger zu verhindern.
  • Schutz vor Integer-Überlauf und -Unterlauf: Nonces, Locktimes, Gas- oder Gebührenlimits und Beträge, die die Sicherheitsgrenzen (MaxInt64) überschreiten oder Unterläufe erzeugen (z. B. wenn der Gesamtausgabewert den Gesamteingabewert überschreitet), werden sofort abgelehnt.
  • Fehlende Gebührenbestätigung: Transaktionen, bei denen keine korrekten Miner-Gebühren oder Gas-Parameter definiert sind, werden automatisch abgelehnt.