
# Fraud rule configuration

Fraud rules decide how each [event](https://trust.myaza.co/documentation/monitoring-events/markdown) is scored and which decision it earns. Configure them under **Rules & Policies → Fraud rules**. Changes apply to events scored afterwards in that environment.

Start in **Rule library** to install a reviewed starter control in one click. Open **Current rules** to tune decision thresholds, currency limits and built-in signals, or choose **Build custom rule** when your integration sends organisation-specific evidence. Library rules use the same versioned, testable rule engine as custom rules, so installation does not introduce a second decision path.

Viewing the configuration is open to anyone with Risk Intelligence access; **editing requires the `monitoring:manage` permission**. Until you save once, an environment runs on the built-in defaults; saving creates an explicit configuration for that environment. **Reset to defaults** reverts the form to the platform defaults.

## How scoring works

1. Every rule inspects the event and produces a **signal** from 0 (no risk) to 1 (maximum).
2. Signals are combined by **weight** using a soft-OR: any one strong signal can push the score high, and additional signals raise it further with diminishing returns.
3. The result is a **composite score, 0–1** (surfaced as 0–100 on events).
4. The score is compared to two cutoffs to produce the **decision**.

```
        ALLOW            REVIEW              BLOCK
  ├──────────────┼──────────────────┼──────────────────┤
  0        review threshold    block threshold        1
```

## Decisions & limits

The first tab, **Decisions & limits**, sets the cutoffs and money ceilings.

### Decision thresholds

| Setting | Meaning |
|---|---|
| **Review threshold** | At or above this score, the event is marked `REVIEW` and an [alert](https://trust.myaza.co/documentation/investigations/markdown) is opened. |
| **Block threshold** | At or above this score, the event is marked `BLOCK`. |

The review threshold must be **less than or equal to** the block threshold.

**Metered billing** (toggle) charges a small per-event fee for scoring in **production** only; sandbox and development are always free.

### Money limits

Amount ceilings are held in a **base currency** (e.g. `USD`) with optional **per-currency overrides**. For each event, the engine picks the ceiling for that event's currency, falling back to the base currency when there's no override.

| Limit | Feeds |
|---|---|
| **Single transaction** | The **Threshold** rule: the most one transaction can be before it flags. |
| **Rolling-window total** | The **Velocity** rule: the most an entity can move in a currency within the velocity window. |

Add a currency to give it its own limits; remove it to fall back to base. Some behavioral rules also take per-currency **minimum amounts** (New-beneficiary, Round-amount).

## Built-in rules

Every rule carries a **weight** (0–1): how strongly it influences the composite score. `0` turns the rule off; `1` gives it full influence. The rules are grouped into three tabs.

### Core rules

Threshold-based checks that work from `amount` / `currency` / `country` / `counterparty` alone.

| Rule | Flags when… | Key config |
|---|---|---|
| **Threshold** | A single event's amount exceeds its currency's single-transaction limit. | weight |
| **Velocity** | Too many events, or too much total value in one currency, across a rolling window. | window (hours), max count, weight |
| **Pattern (structuring)** | A burst of same-currency events sit just under the single-transaction limit (3+ at 70–100% of the limit). | window (hours), weight |
| **Geography** | The event's `country` is on your high-risk or blocked list. | high-risk[], blocked[], weight |
| **Counterparty** | The `counterparty` is on your high-risk or blocked list (one entry per line, case-insensitive). | high-risk[], blocked[], weight |
| **Baseline anomaly** | The amount deviates sharply from what's normal *for this entity* (EWMA per entity, cohort fallback during warm-up). | z-score threshold, weight |

### Flow & velocity

Behavioral patterns across a sequence of events. These need specific `data` fields and stay dormant until you send them.

| Rule | Flags when… | Needs | Key config |
|---|---|---|---|
| **Dormant-then-active** | An account silent for N days suddenly transacts. | — | dormant days, weight |
| **Pass-through** | Money flows in then straight back out in matched amounts (layering). | `direction` | window (hours), match ratio, weight |
| **Rapid movement** | Funds leave almost as fast as they arrive (opposite-direction flow within minutes). | `direction` | window (minutes), weight |
| **Smurfing** | Many distinct senders funnel money into one account. | `direction`, `counterparty` | window (hours), min sources, weight |

### More signals

| Rule | Flags when… | Needs | Key config |
|---|---|---|---|
| **New beneficiary** | A first, sizeable payment to a counterparty never paid before. | `counterparty` | window (hours), min amount, weight |
| **Round amount** | Suspiciously round amounts, exact multiples of a unit at or above a minimum. | `amount` | unit, min amount, weight |
| **Cross-border** | A transaction in a country different from the entity's nationality (elevated if that country is on your geo lists). | entity `nationality`, event `country` | weight |
| **Cash-intensive** | The event moved cash (`channel` = `cash`). | `channel` | weight |
| **Profile change** | The entity performs a transaction `type` it hasn't done before, once it has enough history. | `type` | min history, weight |

> **Match your payload to your rules.** A behavioral rule with a weight but without the fields it needs never fires. The rule-coverage panel flags rules that are weighted but unconfigured. See the [event `data` payload](https://trust.myaza.co/documentation/monitoring-events/markdown#the-data-payload).

## Custom rules

When the built-ins don't cover a scenario, author your own declaratively, with no code. Each custom rule has:

| Field | Purpose |
|---|---|
| **Name** | Machine-readable id, e.g. `high_value_crypto`. Fires as `custom:<name>` on alerts and SAR reports. |
| **Description** | Human label shown on alerts, e.g. "Large crypto transfer". |
| **Enabled** | On/off toggle. |
| **Condition** | The match expression (below). |
| **Score** | Risk contribution (0–1) when the condition matches. |
| **Weight** | How strongly that contribution affects the composite score (0–1). |

You can define up to **50** custom rules per environment.

Before saving a change, choose **Test changes**. Myaza replays recent scored events as a read-only historical test and shows how many decisions would change. The test creates no alerts, investigations, customer updates or charges.

### Conditions

A condition is a tree combining field predicates with `all` (AND), `any` (OR), and `not`. The dashboard offers a **Builder** for flat all/any predicates and an **Advanced (JSON)** mode for arbitrary nesting.

**Fields** you can test: `amount`, `type`, `currency`, `country`, `counterparty`, `direction`, `channel`, `ip`, `entity.riskTier`, `entity.nationality`, and any custom `meta_data.*` path.

**Operators:** `gt` (>), `gte` (≥), `lt` (<), `lte` (≤), `eq` (=), `neq` (≠), `in` (in list), `nin` (not in list), `contains`, `exists`.

```json
{
  "all": [
    { "field": "amount", "op": "gt", "value": 50000 },
    { "field": "currency", "op": "in", "value": ["BTC", "ETH"] }
  ]
}
```

The rule above (named `high_value_crypto`, score `0.8`, weight `0.6`) flags large crypto transfers and contributes to the same composite score as the built-ins. An empty condition never fires, so the editor warns you to add at least one predicate.

## Next steps

- [Event monitoring](https://trust.myaza.co/documentation/monitoring-events/markdown): send events these rules score.
- [Investigations and reporting](https://trust.myaza.co/documentation/investigations/markdown): investigate what the rules flag.
