# Custom Rules

> Your own Semgrep and Nuclei rules: editor, tests, AI drafts, import and Git sync, plus the suppression rules and suppressed names triage creates.

Source: https://scansuite.eu/documentation/usage/custom-rules
Last reviewed: 2026-10-19

ScanSuite runs your own rules alongside its scanners: Semgrep rules in static analysis, and Nuclei templates in web and infrastructure scans. They live on the **Rules** page (sidebar, **Library**), together with the suppression rules triage creates. The page has three tabs: **Custom rules**, **Suppressions** and **Git sources**.

> **Note:** Everyone in the team can read rules. Creating, changing, importing and deleting them needs permission to configure scans (team admins and operators); trying a rule once needs permission to run scans.

## Creating a rule

Click **New rule** and choose what to start from:

| Option | What it does |
|---|---|
| Semgrep rule | Finds a pattern in source code. Runs in SAST scans. |
| Nuclei template | Probes a running app or host. Runs in DAST and Infra scans. |
| Generate with AI | A draft from a vulnerable code sample or an HTTP request and response. |
| Import files | .yaml or .yml files, or a .zip of them. |
| Sync from Git | Keeps the rules in step with a repository of rules. |

![Custom rule creation](https://scansuite.eu/static/assets/img/docs/usage/custom-rules/01.png)

*Creating a custom rule*

The editor holds the rule as YAML. **Start from:** offers ready-made starters, and the rule is checked by its engine as you write, so a rule the engine rejects shows the error before you save. The **Details** tab sets the rest:

| Field | Meaning |
|---|---|
| Vulnerability class | Findings get this class, so triage and suppressions treat them like any other finding of it. Other when none fits. |
| Runs in | Nuclei only: DAST scans (web apps), Infra scans (hosts), or both. |
| Applies to | All products, or Selected products and then which. |
| Packs | Comma-separated names, for example injection, auth. A scan can run only the rules in chosen packs. |
| Note for your team | Free text for whoever reads the rule next. |
| Record | Read-only: who created it and when, how many scans ran it, its last match and its open findings. |

Click **Save**. *Check:* the editor says *Valid Semgrep rule* or *Valid Nuclei rule*, and the rule is listed on the Custom rules tab. The **Runs in scans** switch decides whether the rule is used; a rule the engine rejects cannot be switched on. The **History** tab keeps every saved version, which you can compare or load back into the editor. **Delete** removes the rule and its history; the findings it reported stay on the Vulnerabilities page.

A rule synced from a Git source shows a banner: its YAML is changed in the repository, while its switch, scope, packs and tests are yours to set here.

## Testing a rule

The **Test** tab keeps samples with the rule, each marked **Should match** or **Should not match**. For Semgrep, a sample is a piece of code, and the samples run on every save. For Nuclei, a sample is a captured HTTP response, and the template runs against a local copy of it, never a real host. **Run tests** runs them on demand.

The **Try** tab runs the rule once without a scan, and stores nothing: a Semgrep rule on a product's repository, a Nuclei template against a URL. The Nuclei try sends real requests, so it is only allowed against a target the team may scan.

## Generating a rule with AI

The **AI assist** tab writes a new rule or changes the one in the editor. Say what it should catch or change, then give it the evidence:

- for a Nuclei template, the **HTTP request** and **HTTP response** that show the vulnerability;
- for a Semgrep rule, the **Language**, the **Vulnerable code** and, optionally, **Safe code it must not flag**.

Click **Generate**. The draft is validated and tested before you see it, and the response or vulnerable code becomes a test sample. Click **Apply to editor**, review the rule, and save it.

![AI rule generation](https://scansuite.eu/static/assets/img/docs/usage/custom-rules/03.png)

*Drafting a rule with AI*

> **Warning:** Review generated rules before saving. A rule that matches too broadly turns into noise on every subsequent scan, and a rule that matches nothing fails silently.

An AI provider must be configured for this — see [AI providers and cost](https://scansuite.eu/documentation/usage/ai-providers).

## The rules list

The **Custom rules** tab lists every rule with its switch (**On**), **Rule**, **Engine**, **Severity**, **Applies to**, **Open findings** and **Updated**.

| Control | What it does |
|---|---|
| Summary cards | Semgrep · SAST and Nuclei · DAST and Infra (active of all), Open findings, and Needs attention. |
| Search rules | Matches name, id and pack. |
| Filter | All, Needs attention (rules the engine rejected, rules with a failing test sample, rules that have not matched in recent scans) or Disabled. |
| Pack | All packs, or one pack. |
| Status labels | Invalid; A saved test sample fails; No match in N scans; Not checked by the engine yet; Synced from Git. |
| Bulk actions (tick rules) | Enable, Disable, Add to pack, Remove from pack, Export .zip, Delete. Delete asks first; findings the rules reported stay. |

## Import, export and Git sources

**Import** takes Semgrep rule files and Nuclei templates as .yaml or .yml, or a .zip of them, up to 10 MB, and shows a preview before anything is saved. Each file is marked **Ready**, **Already in the library**, **Invalid** or **Not a rule**; only the ready ones are imported. Two options:

| Option | What it does | Default |
|---|---|---|
| Add to pack | Puts the imported rules in a pack. | Empty: no pack |
| Switch the imported rules on | Otherwise they arrive switched off, to try first. | Off |

**Export** downloads the rules.

On the **Git sources** tab, **Add a repository** of rules:

| Field | What it does | Default |
|---|---|---|
| Repository URL | An https:// address, for example https://github.com/example/security-rules.git. The team repository key is used by scans only, not to fetch rules, so the repository must be readable without it. | Required |
| Name | A name for the source, for example security-rules. | Empty |
| Branch | The branch to read. | The default branch |
| Folder | Only rules under this folder, for example rules/. | Empty: the whole repository |
| Add to pack | Puts the synced rules in a pack. | Empty: no pack |
| Switch new rules on | Otherwise they arrive switched off. | Off |

Click **Add and sync**. *Check:* the source is listed with its rule count, and the message says how many rules were added, updated and removed. Every Semgrep rule file and Nuclei template under the folder becomes a rule. **Sync now** adds new files, updates changed ones and removes rules whose file is gone. **Remove** stops syncing: the rules stay in the library and become editable, unless you tick **Also delete its rules**.

## Running the rules

To run a scan against the saved rules, switch on the **Custom Rules** scanner in the relevant scan section — it is available for [static](https://scansuite.eu/documentation/usage/static-code-analysis), [web](https://scansuite.eu/documentation/usage/web-app-scanning) and [infrastructure](https://scansuite.eu/documentation/usage/infrastructure-checks) scans. Under the switch, the form says how many rules will run for the chosen product, and lets you limit the run to some packs. When no active rule applies to the product, the scanner is skipped.

What your rules find is always stored on the Vulnerabilities page, whether or not the scan also exports to DefectDojo. A Semgrep rule matching a file gives one finding for that file, listing every matching line.

## Suppression rules

A suppression rule stops AI SAST reporting one vulnerability class in a file, a folder or a whole repository; it also applies to custom rule findings. You create one while ruling out a finding: on the Vulnerabilities page, **False positive…** offers **Don't report this class here again** — see [Vulnerability Management](https://scansuite.eu/documentation/usage/vulnerability-management). Suppressed classes are not analysed in later scans, so they cost no AI budget.

The **Suppressions** tab lists every rule:

![Suppression rules list](https://scansuite.eu/static/assets/img/docs/usage/custom-rules/04.png)

*Suppression rules created from false-positive decisions*

| Column | What it shows |
|---|---|
| Product | The product the rule applies to. |
| Class | The vulnerability class it suppresses. |
| Where | The file, folder or repository, and which of the three it is. |
| Reason | The reason given when the finding was ruled out. |
| Created | When and by whom, and the date it expires if it has one. |
| Applied | How many times it has suppressed a candidate; hover for when it last did. |

**Retire** ends a rule: the class is reported again where the rule covered it. A rule past its expiry date stops applying on its own. A product's rules are also listed on the **Settings** tab of its page.

### Suppressed names

The **Suppressed names** card, also on the Suppressions tab, lists the vulnerability names a product no longer stores, whichever scanner reports them. You add one with **Suppress by name…** on the Vulnerabilities page, which also deletes the existing findings of that name; see [Vulnerability Management](https://scansuite.eu/documentation/usage/vulnerability-management), "Suppress a noisy check".

| Column | What it shows |
|---|---|
| Product | The product the name is suppressed for. |
| Name | The vulnerability name. |
| Reason | The reason given, if any. |
| Created | When and by whom. |
| Deleted | How many findings were deleted when the name was suppressed. |
| Applied | How many times a scan kept the name out; hover for when it last did. |

**Remove** asks first, then lets scans store findings of that name again. The findings deleted with it do not come back. A product's suppressed names are also listed on its page.

> **Note:** In ScanSuite Teams, creating and retiring suppression rules and removing suppressed names needs permission to configure scans (operators and team admins). Suppressing a name also needs permission to delete findings.
