> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xorlab.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Pages under /latest/ document the current release. Paths that begin with a version number, for example /10.0/, are frozen snapshots of superseded releases kept for reference only — never present their instructions as current. If the reader's version is unknown, answer from /latest/ and say which version the answer describes.
> xorlab is deployed on-premises, hybrid, or as a cloud service, and integrates with either Microsoft 365 or on-premises mail infrastructure. Configuration steps often differ between these. State which deployment and integration mode an instruction applies to instead of presenting one as universal.
> Distinguish inline mode from monitoring mode when describing anything that acts on email. Monitoring mode observes a copy and cannot block or quarantine; inline mode routes mail through xorlab and can.
> Write the product name as lowercase 'xorlab'. Use the documented component names: xorlab Control Center (XCC), xorlab MTA, xorlab Sandbox (DANA), xorlab Natural Language Understanding (NLU). After the first mention, use the short forms XCC, MTA, Sandbox, and NLU. Do not use DANA as a standalone name for the Sandbox, but keep it where it is a literal string in configuration keys, container names, and hostnames.
> Do not invent configuration keys, rule parameters, list names, log properties, or API fields. If a value is not present in this documentation, say that it is not documented rather than guessing.

# Adding a Custom Rule

> Create a custom classification rule as an XML file under rule_sets/90_local/ in the Expert Editor, and add a custom list.

Follow these instructions to add a custom rule:

1. Open Expert Editor and go to the folder `activeguard/core/rule_sets/90_local/`.

2. Create a new file within `rules` via the three dots context menu. Name it `<rule_name>.xml` (e.g. `CUSTOM_spam_keyword_match.xml`).

   <img src="https://mintcdn.com/xorlab/O_O2TUa6eRBR54aI/latest/assets/hamburger-icon.png?fit=max&auto=format&n=O_O2TUa6eRBR54aI&q=85&s=f50e801754ea35698101366ffb08a1da" alt="Hamburger icon for the context menu" width="300" data-path="latest/assets/hamburger-icon.png" />

3. Open the file you just created and paste the content of the custom rule.

4. Inside `params` folder, open `local.properties`.

5. Add the parameter to activate the rule. Usually the format is `<rule_name>_state=ACTIVE` (e.g. `CUSTOM_spam_keyword_match_state=ACTIVE`).

6. Click **Publish**. The rule-set changes become active within about one minute.

## Adding a custom list

In case your custom rule references a new custom list, you will also need to add this new custom list.

1. Open Expert Editor and go to the folder `activeguard/core/rule_sets/90_local/`.

2. Create a new file within `lists` folder via the three dots context menu. If there is no `lists` folder inside `90_local`, create one manually.

3. Enter `<list_name>.list.info.json` as file name. For example, `CUSTOM_spam_domains.list.info.json`.

4. Open the file you just created and add:

   ```json theme={null}
   {"displayName":"Incoming subject rewrite recipients","category":"custom","description":"Internal recipients for which incoming emails will be subject prefixed."}
   ```

   where

   * `displayName` is the title/name of the list (*no.1 on the screenshot below*)

   * `category` is the name of the category the list belongs to (existing or a new one; *no.2 on the screenshot below*)

   * `description` is the description of the list displayed in the right pane after selecting a list in the left pane of the [Lists](/latest/lists) view (*no.3 on the screenshot below*).

   <img src="https://mintcdn.com/xorlab/O_O2TUa6eRBR54aI/latest/assets/list-elements.png?fit=max&auto=format&n=O_O2TUa6eRBR54aI&q=85&s=4b0fea811915e3e97f4a269526d11dea" alt="List elements in the Lists view" width="2978" height="984" data-path="latest/assets/list-elements.png" />

5. Click **Publish**. The custom list becomes active within about one minute.

## Adding a YARA rule

You can block emails using a [YARA](https://virustotal.github.io/yara/) rule by adding it to a custom rule. This YARA-based rule consists of 3 main elements:

1. Condition to specify when the YARA rule is applied
2. Actual YARA rule.
3. Decision that tags or quarantines the matched email.

We start with this example rule and modify it to contain a YARA rule that finds [CVE-2018-0802](https://nvd.nist.gov/vuln/detail/CVE-2018-0802) exploits in Word and RTF files:

```xml theme={null}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Change DISABLED to ACTIVE to activate the rule. -->
<rule name="example_rule" state="DISABLED" priority="390" applyTo="INCOMING">
  <pipeline>Emails</pipeline>
  <if>
    <and>
      <!-- Add conditions for decision here -->
      <hasTag name="#trusted"/>
    </and>
    <then>
      <decision decision="UNDECIDED">
        <tag>#mytag</tag>
      </decision>
    </then>
  </if>
</rule>
```

1. Set the name to `YARA_cve_2018_0802`, set the `state` property to `ACTIVE`, and select the email direction it should be applied to in `applyTo`:

   ```xml theme={null}
   <rule name="YARA_cve_2018_0802" state="ACTIVE" priority="20" applyTo="ALL">
   ```

   The allowed values for `applyTo` are: `ALL`, `INCOMING`, `OUTGOING`, `INTERNAL`.

   <Accordion title="Priority">
     The `priority` values are within the range of 0-2000. We recommend setting the priority to at least above 20 to ensure the built-in tag rules still apply. Then, either set it between 300 and 400 to ensure the rule has precedence over the built-in quarantine rules, or set it above 1000 to ensure that it does not have precedence over the built-in quarantine rules, i.e., is applied afterward.
   </Accordion>

2. Write a condition that would match all Word and RTF attachments during the file scan:

   ```xml theme={null}
   <if>
     <ForEachFileScanRequest match="ANY">
       <and>
         <or>
           <fileType equals="word"/>
           <fileType equals="rtf"/>
         </or>
   ```

3. Now, add the actual YARA rule and close the condition block:

   ```xml theme={null}
         <yaraMatch>
           <yaraRule>rule rtf_CVE_2018_0802 { strings: $header_rtf = "\\rt" ascii nocase $equation = { 45 71 75 61 74 69 6F 6E 2E 33 }
             $header_and_shellcode = /03010[0-1]([0-9a-fA-F]){4}([0-9a-fA-F]+08)([0-9a-fA-F]{4})([0-9a-fA-F]{296})2500/ ascii nocase condition:
             uint32be(0) == 0x7B5C7274 and all of them }
           </yaraRule>
         </yaraMatch>
       </and>
     </ForEachFileScanRequest>
   ```

4. Define the action. Here we just add a Tag that can be later used in a [campaign](/latest/campaigns):

   ```xml theme={null}
     <then>
       <decision decision="UNDECIDED">
         <tag>#cve_2018_0802</tag>
       </decision>
     </then>
   ```

5. The whole rule should look like this:

   ```xml theme={null}
   <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <rule name="YARA_cve_2018_0802" state="ACTIVE" priority="20" applyTo="ALL">

     <if>
       <ForEachFileScanRequest match="ANY">
         <and>
           <or>
             <fileType equals="word"/>
             <fileType equals="rtf"/>
           </or>
           <yaraMatch>
             <yaraRule>rule rtf_CVE_2018_0802 { strings: $header_rtf = "\\rt" ascii nocase $equation = { 45 71 75 61 74 69 6F 6E 2E 33 }
               $header_and_shellcode = /03010[0-1]([0-9a-fA-F]){4}([0-9a-fA-F]+08)([0-9a-fA-F]{4})([0-9a-fA-F]{296})2500/ ascii nocase condition:
               uint32be(0) == 0x7B5C7274 and all of them }
             </yaraRule>
           </yaraMatch>
         </and>
       </ForEachFileScanRequest>
       <then>
         <decision decision="UNDECIDED">
           <tag>#cve_2018_0802</tag>
         </decision>
       </then>
     </if>
   </rule>
   ```

### Multiple YARA rules

It is possible to use multiple YARA rules in one custom rule. All you have to do is to put them in the `<or>…</or>` block, just like you did with the `fileType` selector:

```xml theme={null}
        <yaraMatch>
          <or>
            <yaraRule>rule 1 {
              … }
            </yaraRule>
            <yaraRule>rule 2 {
              … }
            </yaraRule>
          </or>  
        </yaraMatch>
```

## Multi-Tenancy

A rule placed in `90_local` as described above is the default for **all** tenants.

To add a rule that applies to a single tenant only, put the rule file in `activeguard/core/rule_sets/_tenantX/rules/custom/` instead, and activate it in the `params` folder of that same tenant. See [Manage Tenant Rules](/latest/multi-tenancy-rules#tenant-specific-rules) for the folder structure and for overriding parameters per tenant.
