# Alias rules

> One rule set per alias — conditions, an action, and the gotchas that decide whether mail arrives

Source: https://emailconnect.eu/help/alias-rules/

Alias rules decide which incoming emails reach your webhook. Each alias has **one rule set**: a list of conditions, and **one action** to take when those conditions match.

**Note:** Rules are a Maker+ feature.

## The model in one paragraph

An alias has **one** rule set — not a list of rules. The rule set holds up to **10 conditions**, each joined to the previous one with **AND** or **OR**, plus a single action: **Block**, **Allow**, or **Tag**. When an email arrives, the conditions are evaluated and folded together into one true/false answer, and the action is applied to that answer. There is no "block rule" and "allow rule" side by side on the same alias, and there is no rule ordering or priority — there is only one question and one answer.

If rules are disabled, or the condition list is empty, every email is delivered.

## The three actions

| Action | When the conditions match | When they don't |
|---|---|---|
| **Block** | Email is rejected (optionally with a notice to the sender) | Email is delivered |
| **Allow** | Email is delivered | **Email is rejected** |
| **Tag** | Email is delivered with an `X-EmailConnect-Tagged` header | Email is delivered, untagged |

**Tag never blocks anything.** It marks the message and delivers it, so your webhook consumer can branch on it. If a spam condition is what matched, the payload also carries `X-EmailConnect-Spam-Score`.

## ⚠️ "Allow" is a guest list, not an exception

This is the single most expensive misunderstanding of this feature, so read it twice.

**`Allow` means: accept only what matches, and reject everything else.**

If you set `Allow` with the single condition `Sender address is boss@acme.com`, you have not "allowed Boss through". You have configured the alias to **reject every email on earth that is not from Boss**. Newsletters, customers, your own test messages — all rejected, silently.

That is the correct tool when you genuinely want an exclusive list:

```
Action:    Allow
Condition: Sender address is one of  *@supplier-one.com
```
→ only mail from supplier-one.com is delivered. Everything else is rejected.

It is the **wrong** tool when you want to make an exception to a filter you already have. For that, see the next section.

## Making an exception (the OR pattern)

You cannot add a second rule to carve out an exception, because there is no second rule. The exception and the filter live **in the same rule set**, joined with **OR**.

Say you block spam above a score of 6, but one partner keeps tripping the filter:

```
Action:      Allow
Condition 1: Sender address  is one of  *@trusted-partner.com
Condition 2: OR  Spam score  below  6
```

Read it as: *deliver if (the sender is the partner) OR (the score is under 6)*. Which means an email is blocked only when it is **both** not from the partner **and** scoring 6 or more. The partner always gets through; everyone else is still filtered.

Two things to notice about this pattern:

- The exception is a **skeleton key inside its own rule set.** Because there is only one rule set, an OR-matched sender short-circuits *everything else beside it* — including attachment conditions. If your rule set is `Allow: [Attachment type is one of pdf] OR [Sender address is one of *@boss.com]`, then Boss can send you a `.exe` and it will be delivered. The exception isn't scoped to the spam condition; it is scoped to the whole rule.
- Order matters (see below).

## Conditions fold strictly left to right

There is **no operator precedence**. AND does not bind tighter than OR. The conditions are folded top to bottom, in the order you put them in the editor:

```
A  OR  B  AND  C     evaluates as     (A OR B) AND C
A  AND B  OR   C     evaluates as     (A AND B) OR C
```

So **reordering conditions changes what the rule means.** If you drop an exception at the bottom of the list behind an AND, it stops being an exception. Build the rule in the order you want it read.

## Fields and operators

| Field | Operators offered | Value |
|---|---|---|
| **Sender domain** | `contains`, `is exactly` | `contains`: a substring of the sender's domain — see the warning below. `is exactly`: the whole domain (`@acme.ltd`; the editor adds the `@` if you leave it out). Commas for several |
| **Sender address** | `equals`, `is one of` | A full address (`john@acme.ltd`) or a pattern with `*` as a wildcard (`*@acme.ltd`, `invoices-*@acme.ltd`); commas for several |
| **Recipient address** | `equals`, `is one of` | The address the mail was sent to, or a pattern such as `r-*@in.acme.ltd`; commas for several |
| **Attachment type** | `is one of` | Pick from your enabled file types (Storage settings) |
| **Has attachments** | `equals` | Yes / No |
| **Spam score** | `greater than`, `less than` | A number, 1–15 |

A few things the editor does not tell you:

- **`equals` and `is one of` behave identically on Sender address and Recipient address.** Both do the same match: the exact address, or a pattern where `*` matches any run of characters, anywhere in the value. Pick either. Every entry needs an `@`; the editor will not save `r-` or a bare `*`.
- **Several values, one condition.** Separate values with commas (`acme.ltd, acme.xyz`); the condition matches if any of them does. Spaces around the commas are ignored, and matching is case-insensitive. (Attachment type is a multi-select.)
- **The spam-score operators are strict.** The editor shows them as `>` and `<`, and that is exactly how they compare. A message scoring exactly **7.0** is **not** caught by `Spam score greater than 7`. If you want 7 included, set the threshold to 6.9.

## ⚠️ Don't use "Sender domain contains" for anything security-relevant

**Sender domain `contains` is a raw substring match.** (`is exactly` compares the whole domain and is safe.)

`ceo@trusted-partner.com.evil.io` *contains* `trusted-partner.com`. So a condition `Sender domain contains trusted-partner.com` matches that address — and if it's your OR-ed exception, the attacker's mail sails straight past your spam filter. Anyone who can register a lookalike domain can satisfy the condition.

**Use `Sender domain is exactly`, or `Sender address` with a `*@domain` wildcard, instead:**

```
✅  Sender domain   is exactly  @trusted-partner.com
✅  Sender address  is one of   *@trusted-partner.com
❌  Sender domain   contains    trusted-partner.com
```

`is exactly` compares the whole domain, and the wildcard form matches the *end* of the full address, so `...@trusted-partner.com.evil.io` matches neither. Keep `Sender domain contains` for casual, non-security filtering only — for example tagging.

## Spam score and unscored mail

`Spam score` is a first-class field: you can block on it, tag on it, or OR an exception around it, exactly like sender conditions.

Occasionally a message arrives that was never scored (the scanner did not run for it). A spam condition on such a message is **undecidable** — not zero, not false. When any condition is undecidable and the outcome depends on it, the rule **fails open and the email is delivered**. We would rather hand you an unscored spam email than silently destroy a real one.

## Sender notifications

Under the rule set you can enable **Send sender notification on block**. It only fires on the **Block** outcome (an `Allow` rule that rejects a non-matching email also counts as a block).

- The custom message is **plain text, 500 characters max**.
- Leave it empty to send the default rejection notice.
- Skip notifications when you are filtering spam — a bounce confirms to the spammer that the address is live.

## Blocked mail in your logs

By default a blocked email shows up in your logs as **Rejected**, with its sender, subject and text (never attachment content), until your retention period ends. That lets you check what a rule turned away.

If you would rather keep nothing, tick **Don't store blocked messages** under the rule set. A blocked email is then not stored at all: it never appears in your logs or the API, and no record of it is kept. This covers every block by the rule set, including a spam score condition. The sender notification above still goes out if you have it on.

The trade-off: if a rule blocks something it shouldn't, you have no record to find it by. Leave the option off while you are still tuning a new rule.

## Recipes that actually work

**Reject archives on an alias that should only get documents**
```
Action:      Block
Condition 1: Attachment type  is one of  zip
```
(The attachment-type picker only lists file types you have enabled in **Storage settings** — file types you have blocked account-wide are already handled there and don't need a rule.)

**Documents only (an exclusive list — everything else is rejected)**
```
Action:      Allow
Condition 1: Attachment type  is one of  pdf, docx, xlsx
```

**Drop spam, but never drop mail from your accountant**
```
Action:      Allow
Condition 1: Sender address  is one of  *@accountant.example
Condition 2: OR  Spam score  less than  6
```

**Catch-all: accept only one prefix**

You run a catch-all (`*@in.acme.ltd`) and hand out addresses like `r-<something>@in.acme.ltd`. Everything else on that subdomain is unwanted.
```
Action:      Allow
Condition 1: Recipient address  is one of  r-*@in.acme.ltd
```
`r-anything@in.acme.ltd` is delivered, including `r-abc+news@in.acme.ltd` (a `+tag` is part of the address). Any other address on the subdomain is rejected and does not count toward your quota. Leave **Send sender notification on block** off here: otherwise every random address a spammer tries gets a bounce. Tick **Don't store blocked messages** if you want those rejected addresses to leave no trace in your logs.

**Flag suspicious mail without blocking it**
```
Action:      Tag
Condition 1: Spam score  greater than  4
```
Your webhook receives everything, with `X-EmailConnect-Tagged: spam` and `X-EmailConnect-Spam-Score` on the flagged ones. This is the safest way to tune a threshold before you switch it to Block.

## Troubleshooting

**Everything is being rejected.** You almost certainly have an `Allow` action with a narrow condition. `Allow` rejects everything that does not match. Either switch the action to `Block` and invert the condition, or OR your other traffic back in.

**My exception isn't working.** Check the join. An exception must be OR-ed, and it must be positioned so the left-to-right fold reaches it before an AND narrows the result. `[X] OR [Y] AND [Z]` is `(X OR Y) AND Z` — Z can still veto your exception.

**A spam threshold isn't catching mail scoring exactly at the number.** `greater than` is strict. Lower the threshold by 0.1.

**A rule with an attachment condition let something through anyway.** If any OR-ed condition matched (typically a sender exception), the attachment condition never gets a veto. One rule set means one answer.

**Rules are not taking effect at all.** Confirm the **Enable acceptance rules** toggle is on, that the rule set was saved, and that you are on Maker or above.

## Related topics

- [Whitelist or block sender domains](https://emailconnect.eu/help/whitelist-sender-domains/) — the walkthrough
- [Spam filtering](https://emailconnect.eu/help/spam-filtering/) — where the spam score comes from
- [Alias options](https://emailconnect.eu/help/alias-options-explained/) — other alias configuration
