भाषा संदर्भ

नीतियां लिखने के लिए Rego सिंटैक्स और भाषा सुविधाओं की पूर्ण गाइड

नीतियां Rego में लिखी जाती हैं, जो एक घोषणात्मक नीति भाषा है जिसे जटिल एक्सेस कंट्रोल निर्णयों को व्यक्त करने के लिए डिज़ाइन किया गया है। अनिवार्य भाषाओं के विपरीत जहां आप परिणाम की गणना कैसे करनी है यह वर्णन करते हैं, Rego आपको यह वर्णन करने देता है कि कौन सी शर्तें नीति निर्णय को ट्रिगर करनी चाहिए। यह पृष्ठ 256 Blocks में समर्थित सभी सिंटैक्स और भाषा सुविधाओं को कवर करता है।

नीति संरचना

आपके द्वारा लिखी गई प्रत्येक नीति को 256 Blocks द्वारा आवश्यक बॉयलरप्लेट के साथ स्वचालित रूप से लपेटा जाता है। इसका मतलब है कि आप पैकेज घोषणाओं या डिफ़ॉल्ट मानों की चिंता किए बिना पूरी तरह से अपने नियम लिखने पर ध्यान केंद्रित कर सकते हैं।

सभी नीतियां:

  • आवश्यक package स्टेटमेंट के साथ स्वचालित रूप से लपेटी जाती हैं
  • पूर्व-निर्धारित default deny := false (डिफ़ॉल्ट रूप से अनुमति दें)
  • पूर्व-निर्धारित default denyGasSponsor := false (डिफ़ॉल्ट रूप से प्रायोजन करें)
  • केवल नियम परिभाषित कर सकती हैं, डिफ़ॉल्ट को ओवरराइड नहीं कर सकतीं

मूल नियम सिंटैक्स

नियम नीतियों के निर्माण खंड हैं। एक नियम में एक हेड (नियम का नाम, उदा: deny या denyGasSponsor) और एक बॉडी (शर्तें) होती है। जब बॉडी में सभी शर्तें सत्य होती हैं, तो नियम true का मूल्यांकन करता है।

उदाहरण

# Basic structure: rule_name if { conditions }
deny if {
    input.usd_value > 10000
}

एकाधिक शर्तें (AND तर्क)

जब आप एक ही नियम बॉडी में एकाधिक शर्तें शामिल करते हैं, तो नियम को ट्रिगर करने के लिए सभी शर्तें सत्य होनी चाहिए। प्रत्येक शर्त को निहित रूप से AND के साथ जोड़ा जाता है।

उदाहरण

# Both conditions must be true to deny
deny if {
    input.chain == "ethereum"
    input.usd_value > 1000
}

एकाधिक नियम (OR तर्क)

जब आप एक ही नाम के साथ एकाधिक नियम परिभाषित करते हैं, तो कोई भी मिलान करने वाला नियम नीति को ट्रिगर करेगा। यह नियमों के बीच OR तर्क प्रदान करता है।

उदाहरण

# Either condition triggers denial
deny if {
    input.chain == "ethereum"
}
 
deny if {
    input.usd_value > 10000
}

AND और OR का संयोजन

आप जटिल तर्क के लिए दोनों पैटर्न को जोड़ सकते हैं। प्रत्येक नियम बॉडी आंतरिक रूप से AND तर्क का उपयोग करती है, जबकि एकाधिक नियम उनके बीच OR तर्क प्रदान करते हैं।

उदाहरण

# Deny if: (ethereum AND high-value) OR (any chain AND blocked country)
deny if {
    input.chain == "ethereum"
    input.usd_value > 5000
}
 
deny if {
    input.source_country in {"KP", "IR", "CU"}
}

वेरिएबल असाइनमेंट

वेरिएबल को मान असाइन करने के लिए := ऑपरेटर का उपयोग करें। वेरिएबल मानों को सार्थक नाम देकर और पुन: उपयोग को सक्षम करके आपकी नीतियों को अधिक पठनीय और रखरखाव योग्य बनाते हैं।

नीति-स्तरीय वेरिएबल

नियम बॉडी के बाहर परिभाषित वेरिएबल स्थिरांक के रूप में कार्य करते हैं जिन्हें एकाधिक नियमों द्वारा संदर्भित किया जा सकता है। इन्हें थ्रेशोल्ड, अनुमति सूचियों और ब्लॉक सूचियों के लिए उपयोग करें।

उदाहरण

# Policy-level constants - defined once, used everywhere
max_transaction_value := 50000
blocked_countries := {"KP", "IR", "CU", "SY"}
approved_senders := {"0x742d35cc...", "0xa0b86991..."}
 
deny if {
    input.usd_value > max_transaction_value
}
 
deny if {
    input.source_country in blocked_countries
}
 
deny if {
    not input.from_address in approved_senders
}

स्थानीय वेरिएबल

नियम बॉडी के अंदर परिभाषित वेरिएबल उस नियम के स्थानीय होते हैं। इन्हें मध्यवर्ती गणनाओं के लिए या पठनीयता में सुधार के लिए उपयोग करें।

उदाहरण

deny if {
    # Calculate with a safety margin
    value_with_buffer := input.usd_value * 1.15
    value_with_buffer > 10000
}
 
deny if {
    # Estimate gas cost in wei
    gas_cost := to_number(input.gas_limit) * to_number(input.max_fee_per_gas)
    gas_cost > 1000000000000000000  # 1 ETH in wei
}

तुलना ऑपरेटर

Rego शर्तों का मूल्यांकन करने के लिए मानक तुलना ऑपरेटर प्रदान करता है। ये स्ट्रिंग्स, संख्याओं और अन्य तुलनीय प्रकारों के साथ काम करते हैं।

ऑपरेटरविवरणउदाहरण
==बराबरinput.chain == "ethereum"
!=बराबर नहींinput.chain != "polygon"
>से अधिकinput.usd_value > 1000
>=से अधिक या बराबरinput.usd_value >= 1000
<से कमinput.usd_value < 100
<=से कम या बराबरinput.usd_value <= 100

उदाहरण

# Block high-value transactions on expensive chains
deny if {
    input.chain == "ethereum"
    input.usd_value >= 5000
}
 
# Block transactions below a minimum value (potential spam)
deny if {
    input.usd_value != null
    input.usd_value < 1
}

अंकगणितीय ऑपरेटर

आप अपनी नीति शर्तों के भीतर अंकगणितीय गणना कर सकते हैं। यह थ्रेशोल्ड की गणना करने, गुणक लागू करने या मानों को संयोजित करने के लिए उपयोगी है।

ऑपरेटरविवरणउदाहरण
+जोड़input.usd_value + 100
-घटावinput.usd_value - fees
*गुणाinput.usd_value * 1.1
/भागinput.usd_value / 2
%मॉड्यूलो (शेषफल)input.gas_limit % 1000

उदाहरण

# Apply a 10% buffer when checking limits
deny if {
    input.usd_value * 1.1 > 10000
}
 
# Block if combined value exceeds threshold
deny if {
    total := input.usd_value + 500  # Add estimated fees
    total > 5000
}

तार्किक ऑपरेटर

निहित AND (एकाधिक शर्तें) और OR (एकाधिक नियम) से परे, Rego अधिक जटिल अभिव्यक्तियों के लिए स्पष्ट तार्किक ऑपरेटर प्रदान करता है।

not ऑपरेटर

किसी शर्त को नकारने के लिए not का उपयोग करें। यह विशेष रूप से अनुमति सूची पैटर्न के लिए उपयोगी है जहां आप अनुमति प्राप्त सेट में नहीं होने वाली किसी भी चीज़ को अस्वीकार करना चाहते हैं।

उदाहरण

# Only allow specific chains (deny everything else)
allowed_chains := {"polygon", "base", "arbitrum"}
 
deny if {
    not input.chain in allowed_chains
}

उदाहरण: अन्य शर्तों के साथ संयोजन

# Deny if NOT a read-only method AND value is high
deny if {
    not input.rpc_method in {"eth_call", "eth_getBalance"}
    input.usd_value > 1000
}

सहायक नियम

deny और denyGasSponsor से परे, आप जटिल तर्क को व्यवस्थित करने के लिए अपने स्वयं के कस्टम नियम परिभाषित कर सकते हैं। सहायक नियम पुन: प्रयोज्य निर्माण खंड के रूप में कार्य करते हैं जो आपकी नीतियों को अधिक पठनीय और रखरखाव योग्य बनाते हैं।

एक सहायक नियम केवल एक नामित शर्त है जो जब इसकी बॉडी मेल खाती है तो true का मूल्यांकन करती है। फिर आप इन नियमों को अपने deny या denyGasSponsor नियमों में संदर्भित कर सकते हैं, जिसमें उन्हें नकारने के लिए not ऑपरेटर शामिल है।

उदाहरण

# Define a helper rule to check if request is from a trusted source
is_trusted if {
    input.source_country in {"US", "GB", "DE"}
    input.source_ip in {"203.0.113.10", "203.0.113.11"}
}
 
# Define another helper for high-risk transactions
is_high_risk if {
    input.usd_value > 10000
}
 
is_high_risk if {
    input.source_country in {"RU", "CN"}
}
 
# Use helper rules in deny conditions
deny if {
    not is_trusted
    is_high_risk
}

सहायक नियम विशेष रूप से इसके लिए उपयोगी हैं:

  • पुन: प्रयोज्यता: एक बार शर्त परिभाषित करें, इसे कई नियमों में उपयोग करें
  • पठनीयता: जटिल शर्तों को सार्थक नाम दें
  • निषेध: not का उपयोग करके जांचें कि शर्त कब पूरी नहीं होती
  • संगठन: जटिल नीतियों को तार्किक घटकों में विभाजित करें

स्ट्रिंग संचालन

स्ट्रिंग्स डबल कोट्स ("") में संलग्न वर्णों का अनुक्रम हैं। अधिकांश इनपुट फ़ील्ड जैसे input.chain, input.rpc_method, और पते स्ट्रिंग हैं। Rego स्ट्रिंग्स के साथ काम करने के लिए कई अंतर्निहित फ़ंक्शन प्रदान करता है, जो पतों, विधि नामों और अन्य टेक्स्ट फ़ील्ड पर पैटर्न मिलान के लिए आवश्यक हैं।

फ़ंक्शनविवरणरिटर्न
contains(string, substring)जांचें कि स्ट्रिंग में सबस्ट्रिंग है या नहींboolean
startswith(string, prefix)जांचें कि स्ट्रिंग उपसर्ग से शुरू होती है या नहींboolean
endswith(string, suffix)जांचें कि स्ट्रिंग प्रत्यय से समाप्त होती है या नहींboolean
lower(string)लोअरकेस में बदलेंstring
upper(string)अपरकेस में बदलेंstring
substring(string, start, length)स्ट्रिंग का हिस्सा निकालेंstring
sprintf(format, values)मानों के साथ स्ट्रिंग फॉर्मेट करेंstring

उदाहरण

# Block any method containing "sign" (covers eth_sign, personal_sign, etc.)
deny if {
    contains(input.rpc_method, "sign")
}
 
# Block addresses starting with known malicious prefix
deny if {
    startswith(lower(input.to_address), "0x000000000000000000000000000000000000dead")
}
 
# Block debug and admin methods
deny if {
    startswith(input.rpc_method, "debug_")
}
 
deny if {
    startswith(input.rpc_method, "admin_")
}

ऐरे संचालन

ऐरे मानों की क्रमबद्ध सूचियाँ हैं, जो वर्ग कोष्ठक [] के साथ परिभाषित होती हैं। सेट के विपरीत, ऐरे तत्वों के क्रम को संरक्षित करते हैं और डुप्लिकेट शामिल कर सकते हैं। आप नीतियों में ऐरे के साथ अक्सर काम करेंगे, विशेष रूप से input.contract_addresses जिसमें अनुरोध में शामिल सभी कॉन्ट्रैक्ट पते होते हैं।

# Array syntax
my_array := ["first", "second", "third"]

Rego ऐरे का निरीक्षण और काम करने के कई तरीके प्रदान करता है।

फ़ंक्शनविवरणरिटर्न
count(array)तत्वों की संख्याnumber
array[index]इंडेक्स द्वारा तत्व तक पहुंचें (0-आधारित)element
value in arrayजांचें कि ऐरे में मान मौजूद है या नहींboolean

उदाहरण

# Limit the number of contracts in a single request
deny if {
    count(input.contract_addresses) > 10
}
 
# Check if a specific address is in the contract list
deny if {
    "0xbanned..." in input.contract_addresses
}
 
# Access specific array elements
deny if {
    count(input.contract_addresses) > 0
    first_contract := input.contract_addresses[0]
    startswith(first_contract, "0xdead")
}

सदस्यता परीक्षण

सदस्यता परीक्षण नीतियों में सबसे आम संचालनों में से एक है। आप इसका उपयोग यह जांचने के लिए करेंगे कि मान अनुमति सूचियों, ब्लॉक सूचियों या अनुमत मानों के अन्य संग्रह से संबंधित हैं या नहीं।

सेट

सेट अद्वितीय मानों के अव्यवस्थित संग्रह हैं, जो घुंघराले ब्रेसिज़ {} के साथ परिभाषित होते हैं। यह परीक्षण करने के लिए कि कोई मान सेट में मौजूद है या नहीं, in ऑपरेटर का उपयोग करें।

# Set syntax
my_set := {"value1", "value2", "value3"}

सेट तेज सदस्यता परीक्षण के लिए अनुकूलित हैं, जो उन्हें अनुमति सूचियों और ब्लॉक सूचियों के लिए आदर्श बनाता है।

उदाहरण

# Block requests from sanctioned countries
blocked_countries := {"KP", "IR", "CU", "SY", "RU"}
 
deny if {
    input.source_country in blocked_countries
}
 
# Only allow specific chains
allowed_chains := {"polygon", "base", "arbitrum"}
 
deny if {
    not input.chain in allowed_chains
}

इनलाइन बनाम नामित सेट

आप नियमों के भीतर इनलाइन सेट परिभाषित कर सकते हैं या नीति स्तर पर नामित वेरिएबल के रूप में। नामित सेट पठनीयता में सुधार करते हैं और कई नियमों में पुन: उपयोग की अनुमति देते हैं।

उदाहरण

# Inline set - good for simple, one-off checks
deny if {
    input.rpc_method in {"eth_sign", "personal_sign", "eth_signTypedData"}
}
 
# Named set - better for reusability and readability
approved_contracts := {
    "0xdac17f958d2ee523a2206206994597c13d831ec7",  # USDT
    "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",  # USDC
    "0x6b175474e89094c44da98b954eedeac495271d0f"   # DAI
}
 
deny if {
    some addr in input.contract_addresses
    not addr in approved_contracts
}

some के साथ पुनरावृत्ति

some कीवर्ड आपको संग्रहों पर पुनरावृत्ति करने और प्रत्येक तत्व के विरुद्ध शर्तों की जांच करने देता है। यह input.contract_addresses जैसे ऐरे के साथ काम करते समय आवश्यक है।

मूल पुनरावृत्ति

यह जांचने के लिए some का उपयोग करें कि संग्रह में कोई भी तत्व शर्त से मेल खाता है या नहीं।

उदाहरण

# Deny if ANY contract address is in the blocklist
blocked_contracts := {"0xbanned1...", "0xbanned2..."}
 
deny if {
    some addr in input.contract_addresses
    addr in blocked_contracts
}

इंडेक्स के साथ पुनरावृत्ति

आप पुनरावृत्ति के दौरान प्रत्येक तत्व के इंडेक्स तक भी पहुंच सकते हैं।

उदाहरण

# Check conditions on specific positions
deny if {
    some i, addr in input.contract_addresses
    i == 0  # First contract only
    startswith(addr, "0x000")
}

उदाहरण: कोई भी मिलान खोजना

# Deny if any contract starts with a suspicious prefix
deny if {
    some addr in input.contract_addresses
    startswith(lower(addr), "0x000000000000000000000000")
}
 
# Deny if any contract is not in the approved list
approved := {"0xusdt...", "0xusdc...", "0xdai..."}
 
deny if {
    some addr in input.contract_addresses
    not addr in approved
}

every के साथ पुनरावृत्ति

जबकि some जांचता है कि कोई भी तत्व मेल खाता है या नहीं, every के लिए आवश्यक है कि सभी तत्व एक शर्त से मेल खाएं। यह यह सुनिश्चित करने के लिए उपयोगी है कि संपूर्ण संग्रह आपके मानदंडों को पूरा करे।

उदाहरण

# Deny only if ALL contracts are from a suspicious set
# (unlikely to be legitimate if every address is suspicious)
suspicious_prefixes := {"0x0000000000000000"}
 
deny if {
    count(input.contract_addresses) > 0
    every addr in input.contract_addresses {
        some prefix in suspicious_prefixes
        startswith(addr, prefix)
    }
}

उदाहरण: सत्यापन पैटर्न

# Ensure all contracts are from approved list (inverse of some/not)
approved_contracts := {"0xusdt...", "0xusdc...", "0xdai..."}
 
# This denies if ANY contract is not approved
deny if {
    some addr in input.contract_addresses
    not addr in approved_contracts
}
 
# Equivalent using every (deny if NOT every contract is approved)
deny if {
    count(input.contract_addresses) > 0
    not every addr in input.contract_addresses {
        addr in approved_contracts
    }
}

कॉम्प्रिहेंशन

कॉम्प्रिहेंशन आपको मौजूदा संग्रहों को रूपांतरित या फ़िल्टर करके नए संग्रह बनाने देते हैं। ये विशिष्ट मानों को निकालने या व्युत्पन्न डेटासेट बनाने के लिए उपयोगी हैं।

ऐरे कॉम्प्रिहेंशन

कुछ मानदंडों से मेल खाने वाले तत्वों से एक नया ऐरे बनाएं।

उदाहरण

# Extract all contract addresses that start with a specific prefix
matching_contracts := [addr |
    some addr in input.contract_addresses
    startswith(addr, "0xa")
]
 
deny if {
    count(matching_contracts) > 3
}

सेट कॉम्प्रिहेंशन

अद्वितीय मानों का एक सेट बनाएं।

उदाहरण

# Get unique prefixes from all contract addresses
contract_prefixes := {substring(addr, 0, 6) |
    some addr in input.contract_addresses
}
 
# Deny if there are too many different contract prefixes (suspicious)
deny if {
    count(contract_prefixes) > 5
}

सशर्त Else

else कीवर्ड आपको फ़ॉलबैक मान परिभाषित करने देता है जब शर्तें पूरी नहीं होती हैं। यह इनपुट के आधार पर भिन्न होने वाले व्युत्पन्न मानों की गणना के लिए उपयोगी है।

उदाहरण

# Assign risk level based on transaction value
risk_level := "critical" if {
    input.usd_value > 100000
} else := "high" if {
    input.usd_value > 10000
} else := "medium" if {
    input.usd_value > 1000
} else := "low"
 
# Use the computed risk level in deny rules
deny if {
    risk_level == "critical"
}
 
denyGasSponsor if {
    risk_level in {"high", "critical"}
}

उदाहरण: चेन-विशिष्ट थ्रेशोल्ड

# Different limits for different chains
chain_limit := 1000 if {
    input.chain == "ethereum"
} else := 5000 if {
    input.chain == "polygon"
} else := 10000
 
deny if {
    input.usd_value > chain_limit
}
भाषा संदर्भ | 256 Blocks