Custom Detections
Custom detections let your team turn a Hunt Lab query into a scheduled detection that raises observations in SenseOn whenever the query matches. They run alongside the detections SenseOn builds and maintains for you, giving you a way to codify the threats, behaviours, and hygiene checks that matter most in your environment.
Availability: Custom detections are released per tenant behind a feature flag (
senseon.custom_detections.enabled). If you do not see Custom Detections under Settings, the feature is not yet enabled for your organisation. Contact SenseOn support to discuss enabling it.
How a Custom Detection Works
A custom detection is built around a Hunt Lab query. On a schedule you choose, SenseOn runs the query over a recent window of telemetry and turns each row it returns into an observation. Every such observation takes the detection's name as its title, with the detail coming from the description you define. These observations appear in Experience and feed into cases like any other observation.
A custom detection moves through the following lifecycle:
- Author the query in Hunt Lab. Detections are always created from a query, so the journey starts in Hunt Lab.
- Create the detection. Set the schedule, severity, observation text, and the controls that govern how often and how many observations it raises, either directly in the form or by describing the detection to Horus (see Creating a Custom Detection from Hunt Lab).
- Preview. Run the query from the form to see the rows it returns and the observations they would raise, before you save.
- Save and monitor. Once saved, the detection runs on its schedule. The edit view shows the result of its most recent run, and links straight to the observations it has produced.
Who Can Access Custom Detections
When the feature is enabled for your organisation, any signed-in user can open Settings > Custom Detections and view the list of detections.
Creating, editing, enabling, disabling, and deleting detections requires the detections write permission (ui/edit/detections). Users without it see the list in read-only mode, so they can review existing detections but cannot change them.
Creating a Custom Detection from Hunt Lab
Availability: The chat authoring experience is provided by the AI Detection Author feature (
senseon.llm.detection_author.enabled). It is opt-in and off by default, and requiressenseon.custom_detections.enabledto also be on. Root and Admin roles can enable it. When it is off, Create detection falls back to the detection form documented in this section.
- Open Hunt Lab and write the query that identifies the activity you want to detect.
- Run the query. Create detection appears in the Hunt Lab toolbar as soon as you start typing, but stays disabled until the current query has run successfully. While it is disabled, a tooltip prompts you to "Run the query successfully first to create a detection". Once it is available, the tooltip reads "Create a detection from this query".
- Select Create detection. When AI Detection Author is enabled, this opens the Horus Author a detection chat with the query you just ran seeded as the opening message. When it is off, SenseOn carries the query you just ran across to the detection form.
- Complete the detection form and Save.
The button follows your latest run. If you edit the query after running it, Create detection disables again until you re-run the edited query. This keeps every detection tied to a query you have just seen results for.
Why start in Hunt Lab? A detection is only as good as the query behind it. Building and running the query in Hunt Lab first lets you confirm it returns what you expect before you turn it into a scheduled detection.
Starting from the Custom Detections page. Settings > Custom Detections also carries a Create detection button, and offers the same action from its empty state when you have no detections yet. Because a detection is always authored from a query, this button takes you to Hunt Lab with an empty query rather than opening the form directly. Write and run your query there, then continue from step 2 above.
Authoring with Horus
How Horus helps you turn a Hunt Lab query into a detection depends on whether the AI Detection Author feature is enabled.
Chat path (when AI Detection Author is enabled). Create detection opens the Author a detection chat, headed "Author a detection" with the subtitle "Describe what you want to detect and Horus will draft a detection rule with you." Horus opens with "I'll ground this against your telemetry, draft a query, check it returns rows, then show you a rule to review. Nothing is saved until you confirm." The Hunt Lab query you just ran seeds the opening message, rendered as a code block. From there, Horus works through the sequence:
- grounds the query against your telemetry
- drafts a query and checks it returns rows
- confirms with you through the "Shape this into a rule?" prompt before drafting, a confirm-to-proceed prompt with a single Yes, shape the rule option that only asks your permission to draft a rule, rather than presenting one itself
- presents the draft as an editable card headed "Draft detection rule", with name, query, schedule, severity, deduplication, and the rest, for you to review and adjust. Confirming it (Confirm and map entities) moves you on to entity mapping rather than saving
- proposes a "Suggested entity mapping" card for you to review. Accepting it (Accept mapping) saves the rule to your Custom Detections, at which point a confirmation reading "Rule saved to your Custom Detections." appears
If the save is refused, the chat reports "The rule could not be saved." rather than staying silent. Accepting the mapping is not by itself confirmation that the rule was stored, so check for one of these two messages before you consider the detection created.
A rule Horus drafts follows the same query requirements and observation title and description conventions as one you build on the form.
Form fallback path (when the feature is off). Create detection takes you to the create form, where Horus reviews your query and drafts a detection-ready version of it for you. A raw exploratory query rarely runs as a detection unchanged, because it needs the right time bounds, an explicit timestamp column, and named columns rather than SELECT *. Horus adapts the query to meet these query requirements and suggests a name, observation text, and deduplication columns. While Horus works, a banner reads "Horus is drafting the query and observation fields — you can fill in the rest while it works.", and the drafted fields are briefly locked while every other field stays editable. If Horus cannot help, the form keeps your original query and shows a quiet notice reading "Horus couldn't prepare the query, so your original Hunt Lab query is shown. Review the fields and run the preview before saving." with a Try again option. Horus never saves the detection for you, so you always review the result and run a preview before saving. This form is the create fallback when the AI Detection Author feature is off. It is also the edit surface for every detection regardless of the flag, so editing an existing detection, however it was created, always opens it in the form.
The Detection Form
This section describes the form used on the create fallback path and whenever you edit a detection. The same query requirements and observation conventions also govern the rule Horus drafts in the chat. Required fields must be completed before you can save.
| Field | What it controls |
|---|---|
| Name | A short, descriptive name for the detection. This also becomes the observation title shown on every observation the detection raises. See Observation title and description. |
| Description (optional) | What the detection looks for and why it matters. |
| Detection query | The CHSQL query that defines the detection. See Query requirements. |
| Frequency | How often the detection runs, for example every 15 minutes through to every 24 hours. |
| Lookback | How far back over telemetry each run scans, for example the last hour through to the last 7 days. |
| Severity | The severity assigned to observations the detection raises: Info, Low, Medium, High, or Critical. |
| Category (optional) | A free-text grouping for the detection, for example Execution. |
| MITRE ATT&CK techniques (optional) | One or more MITRE ATT&CK techniques to tag the detection with, chosen from SenseOn's curated catalogue. See Tagging MITRE ATT&CK techniques. |
| Observation description (optional) | Detail shown on each observation. Supports {{Column}} tokens that are filled in per row. |
| Deduplication columns | The columns that identify a unique result, used to group repeats. See Deduplication, suppression, and limits. |
| Suppression window (hours) | How long a repeat of the same result is suppressed before it raises another observation. |
| Max observations per run | A cap on the number of observations a single run can record. |
| Enabled | Whether the detection is active. When on, the field reads "Enabled — this detection is scheduled to run". Disable to pause it without deleting it. |
Query requirements
Detection queries follow a few rules beyond ordinary Hunt Lab queries, so that each run produces well-formed, time-bounded observations:
- Bound the time predicate with the
window_startandwindow_endidentifiers rather than the{since}and{until}placeholders used in ad-hoc Hunt Lab queries. SenseOn supplies the window for each run based on the detection's lookback. - Project an
AS TIMESTAMPcolumn so each result carries the time the activity occurred. - Avoid
SELECT *and list the columns you need explicitly. - The deduplication columns and any
{{Column}}tokens you reference in the observation text must appear in the query's projection.
These rules are checked when you save. If a query does not meet them, the form lists the validation errors under "This detection could not be saved:" so you can correct the query before saving.
Observation title and description
The observation title is the Name you give the detection. It is a stable title, so every observation the detection raises carries the same title and the detection reads consistently across Experience and its filters. Because the title is fixed, keep per-row detail out of the name and do not use {{Column}} tokens in it.
Put row-specific detail in the observation description instead. The description supports {{Column}} tokens, so wrap a column name in double braces (for example, Process {{process_name}} contacted {{url}}.) and SenseOn fills in the value from each matching row. Any column you reference this way must appear in the query's projection.
Deduplication, suppression, and limits
These controls stop a busy query from flooding you with near-identical observations:
- Deduplication columns define what makes a result unique. Rows that share the same values in these columns are treated as the same finding. Remove a column to merge more findings together, or keep more columns to merge only exact matches.
- The suppression window sets how long a repeat of the same finding is held back before it raises a fresh observation.
- Max observations per run caps how many observations a single run can record, as a safeguard against an over-broad query.
Tagging MITRE ATT&CK techniques
Tag the detection with one or more MITRE ATT&CK techniques, chosen from SenseOn's curated catalogue rather than typed in free text.
Select Add techniques to open a menu with a search box and a checkbox list of techniques. Use the search box to filter the catalogue by technique ID or name. The techniques you select appear beneath the field as removable chips, for example T1059.001 — PowerShell. Removing a chip deselects that technique. You cannot remove chips while the form is saving.
The menu handles a few states as it loads the catalogue:
- While the catalogue loads, the menu shows a loading spinner.
- If it fails to load, the menu shows an error, with a Try again option.
- If the catalogue is empty, the menu shows a "No techniques available" message.
- If your search matches nothing, the menu shows a no-match message.
Previewing a Detection
When you open the form from Hunt Lab (the fallback path used when the AI Detection Author feature is off), SenseOn runs an initial preview for you automatically, so the Query results table and deduplication options are populated without a manual run. If Horus then rewrites your query into a detection-ready draft, the preview re-runs against that draft, so the results you see reflect the query Horus prepared rather than your original Hunt Lab query. After that, select Run query to refresh the preview whenever you change the query, lookback, or observation description.
Before saving, select Run query on the form to dry-run the current query and observation templates. The preview scans the same window the scheduled detection would use, which is the value set in the Lookback field, so changing the lookback changes the rows the preview returns. The preview has two tabs:
- Query results shows a table of the columns and rows the query returns. If nothing matches, it reads "No rows matched".
- Observations raised shows each returned row rendered as the observation it would raise, taking the detection's name as its title and filling the description in from that row. The title is the detection name, so it reads the same on every row and only the description varies. The preview reflects any unsaved edits to the description.
If more rows match than are shown, the preview notes that it is showing the first rows and that more matched. If the query fails, the preview shows the database error inline, and the results from your last successful run stay in view, so you can fix the query and run it again.
The preview also populates the deduplication columns options from the columns your query returns, so you can pick from the available columns rather than typing them. On the create form, SenseOn loads these options automatically once your query is in place, and you can run the query again at any time to refresh them after you change the projection. On an existing detection, its saved deduplication columns remain selectable even before you run a preview.
Managing Detections
Go to Settings > Custom Detections to see every detection configured for your organisation. The list shows each detection's status, name (with its underlying analytic id), severity, who created it, and the result of its last run.
From the list you can:
- Enable or disable a detection with its status toggle. Disabling pauses the detection without removing it.
- Edit a detection to open the form.
- Delete a detection. You are asked to confirm before it is removed.
Enabling, disabling, editing, and deleting all require the detections write permission.
The list shows up to 25 detections per page. When your organisation has more than one page of detections, a pager appears beneath the list so you can move between them, and with a single page it stays hidden. Deleting a detection refreshes the current page, stepping back a page if you removed the last detection on it, so the page you are viewing always reflects the detections the server holds.
If the list cannot be loaded, the page shows "Detection rules could not be retrieved" with a Reload option.
Last run and observations
When you open a detection for editing, a Last run summary shows the outcome of its most recent run:
- The run status, which is Success, Failed, or Running.
- When it last ran.
- How many observations it raised and how many rows it matched.
- For a failed run, the error message from that run.
- A "This detection hasn't run yet." state if it has not run since being created.
Select View in Experience to open the observations this detection has produced in Experience, filtered to this detection by its analytic id. Experience shows the last 28 days by default, so widen the date range there if you need to see observations from further back.
Related
- Hunt Lab Overview is where detection queries are written and run.
- Hunt Lab Training covers CHSQL and the telemetry schema.
- Experience is where the observations a detection raises appear.
- SenseOn AI Architecture has more on Horus and the other SenseOn AI agents.