The objects
A policy is a named, ordered list of rules. Your organization has at most one policy inenforced status at a time. Any others are drafts or archived versions.
A rule has three parts:
- Conditions: a list of comparisons against the request, such as
amount_usd greater_than 10000. Every condition in a rule must match for the rule to match. - An action: what happens when the rule matches. One of
allow,block,require_approval,delay, oralert. - An order: the rule’s position in the list. Lower numbers run first.
field, an operator, and a value. The value goes in value, values, or min and max, depending on the operator. See Condition values.
First match wins
The engine walks the rules inorder, from first to last. For each rule it checks the conditions in turn, and stops at the first condition that fails. The first rule whose conditions all match is the terminal rule: its action becomes the decision, and the rules after it are not evaluated.
Three consequences follow, and most policy bugs come from one of them:
- Order is meaning. A broad
allowplaced above a narrowblockmakes theblockunreachable. Put the most specific and most restrictive rules first. - Conditions within a rule are AND. To express “chain is Tron or chain is Ethereum”, use one condition with the
inoperator, not two conditions. - Rules are OR. To express “block if A, and separately block if B”, write two rules.
shadowed_by_different_action.
What the engine can see
A condition can compare any request attribute the engine evaluates. These include:
Rule reference describes each field. Saving a rule with a field the engine doesn’t know returns
400 invalid_condition_field.
When no rule matches
If no rule matches, the request is allowed. A dry-run returns"result": "approved" and a trace in which every rule has matched: false. The same result comes back, with the reason “No active policy and no quorum”, when your organization has nothing enforced.
So a policy that only lists what to block or hold allows everything else. If you want a default-deny posture, write the allow rules first and finish with a block rule that catches what’s left.
Don’t rely on an implicit default for anything security-relevant. End your rule list with an explicit decision for the cases you care about, and confirm the behavior by dry-running a request that matches none of your other rules. See Test rules with dry-run evaluation.
Actions and the transaction status they produce
A held transaction is persisted and its funds are locked. It does not need to be resubmitted: it executes on its own once it is approved or its time lock expires. Handle held and rejected transactions covers the integration side.
Categories
Every policy has acategory: access, whitelist, limits, approvals, velocity, compliance, or quorum. If you leave it out, it defaults to access. The category describes what the policy is for and controls how it is evaluated. quorum is reserved for the policy that governs administrative changes, described in Policy lifecycle and quorum.
Rule reference lists the categories.