# Derived Detections

## Overview

You can create one or more Derived Detections from a single Base Detection in Panther. Derived Detections inherit the Base Detection's core logic, which is immutable, as well as its metadata and alert field values, which can be overwritten.

Detection derivation is available for rules created as [Simple Detections](https://docs.panther.com/detections/..#simple-detections) or [Python Detections](https://docs.panther.com/detections/rules/python).

### Use cases for Derived Detections

Derivation can be particularly useful when:

* You maintain multiple copies of the same rule, each with different metadata
* In the CLI workflow, you use and customize [Panther-managed rules](https://docs.panther.com/detections/panther-managed), and want to avoid having to resolve merge conflicts when Panther releases updates
  * See a full example on [Using Derived Detections to Avoid Merge Conflicts](https://docs.panther.com/detections/rules/derived/using-derived-detections-to-avoid-merge-conflicts)
* You'd like the ability to, while responding to an incident, deploy multiple variations of one detection to gather telemetry that can inform your next decision
* One member of your team (e.g., a Head of Threat Research) would like to create a set of Base Detections that others (e.g., SOC Analysts) can modify

## Base Detections and Derived Detections

A Base Detection is any custom or [Panther-managed](https://docs.panther.com/detections/panther-managed) rule from which a Derived Detection has been created.

A Derived Detection is created from a Base Detection and:

* Inherits the core detection logic of the Base Detection
  * The core detection logic is defined in the Base Detection's `rule()` function (for Python detections) or `Detection` field (for Simple Detections).
  * A Derived Detection cannot specify its own detection logic—if in the CLI workflow a Derived Detection includes a `Detection` key, for example, its contents will be ignored.
* Inherits the Base Detection's metadata/alert field values, but can overwrite certain fields
  * See [Limitations of detection derivation](#limitations-of-detection-derivation) for a full list of fields that can be overwritten today.
  * An override made in a Derived Detection completely replaces the field's value it inherited from the Base Detection. For example, if both a Base Detection and Derived Detection define an [Inline Filter](https://docs.panther.com/detections/rules/inline-filters) (in the `InlineFilters` key in the CLI workflow or **Filter to only include events** field in the Console), only the Derived Detection's Inline Filter will be applied.
  * Overrides can only be made in one direction, i.e., overrides made on a Derived Detection do not affect Base Detection values. For example, if a Base Detection has `Enabled: False` and its Derived Detection has `Enabled: True`, only the Derived Detection will be enabled.

### What happens when a Base Detection is updated

When the core logic of a Base Detection is updated, the change is propagated to all associated Derived Detections.

When the metadata of a Base Detection is updated, if an associated Derived Detection has already overwritten the value(s) of the updated field(s), there is no change. If an associated Derived Detection has not overwritten the value(s) of the updated field(s), the metadata update is propagated to the Derived Detection.

### Disable Base Detections to avoid duplicate alerts

In most cases, Base and Derived Detections are run over the same set of incoming logs (although it is possible to use [Inline Filters](https://docs.panther.com/detections/rules/inline-filters) to target different events). In this scenario, because the detections share core logic, if they are both enabled, they will generate duplicate alerts.

To avoid this, disable the Base Detection. When a disabled Base Detection is updated, its changes will still propagate to its Derived Detections [as described above](#what-happens-when-a-base-detection-is-updated).

#### Automatically disabling Base Detections in the CLI workflow

In the CLI workflow, there are two ways that you can automatically disable Base Detections:

* **Option 1 (Recommended)**: Add the following setting to your `.panther_settings.yml` file:

  ```yaml
  auto_disable_base: true
  # ... other settings ...
  ```
* **Option 2**: Use `--auto-disable-base` with the [Panther Analysis Tool `upload` command](https://docs.panther.com/panther-developer-workflows/detections-repo/pat/pat-commands#upload-uploading-packages-to-panther-directly).
  * When following this option, note that `--auto-disable-base` must be used with every subsequent upload invocation. If it is omitted, Base Detections will be re-enabled.

{% hint style="warning" %}
If one or more of your Base Detections has already been uploaded to your Panther instance in an enabled state and you then use one of the above methods to automatically disable Base Detections, ensure you are not including `--filter enabled: true` on your [PAT `upload` command](https://docs.panther.com/panther-developer-workflows/detections-repo/pat/pat-commands#upload-uploading-packages-to-panther-directly). If you do, Base Detections will be disabled before `upload` (when the `enabled: true` filter is applied), meaning the newly disabled Base Detections won't be re-uploaded to your Panther instance (leaving them as-is, or enabled).
{% endhint %}

## How to create a Derived Detection

{% tabs %}
{% tab title="Panther Console" %}
**Creating a Derived Detection in the Panther Console**

1. In the left-hand navigation bar of the Panther Console, click **Detections**.
2. Locate the detection you would like to become the Base Detection for a new Derived Detection, and click its name.
3. In the upper-right corner, click `...`.
4. Click **Derive**:\ <img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-76e78c4dfce2f10d543e063c220b754f6758b6f3%2FScreenshot%202023-11-09%20at%2012.04.44%20PM.png?alt=media" alt="In the Panther Console, the three dots menu on a detection&#x27;s page is open, and the Derive option is circled." data-size="original">
5. On the **Basic Info** page, optionally edit the **Name** and **ID** fields for the Derived Detection.
   * Ensure the name is distinguishable from the Base Detection's name.
6. Click **Continue**.
7. Scroll down to the **Filter** and **Set Alert Fields** sections, and set desired overrides to Inline Filters and alert fields:\
   ![The edit detection page in the Panther Console is shown. A Filter section is visible, along with a Set Alert Fields section. Within the latter are sub-sections for Required Fields and Optional Fields.](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-3a5d463bf5186c6ea31672fc18baa66c63f2e850%2FScreenshot%202023-11-14%20at%2012.24.35%20PM.png?alt=media)
8. In the upper-right corner, click **Deploy**.
   * The detection will have a `DERIVED` label:\ <img src="https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-ff5df9a84be3cd8e9b66db69e181bd778f7a176f%2FScreenshot%202023-11-14%20at%2012.31.51%20PM.png?alt=media" alt="The word &#x22;DERIVED&#x22; is shown in teal." data-size="original">
     {% endtab %}

{% tab title="CLI workflow" %}
**Creating a Derived Detection in the CLI workflow**

1. In the directory where you use the [Panther Analysis Tool (PAT)](https://docs.panther.com/panther-developer-workflows/detections-repo/pat), create a new YAML file for your Derived Detection.
2. In this YAML file, add the following fields, which are required for Derived Detections:
   * `BaseDetection`: Provide the rule ID of any rule currently present in your Panther instance or in the local directory you will upload using PAT.
     * The `BaseDetection` key is the link between this Derived Detection and its Base Detection, and is what indicates that inheritance should be applied.
   * `RuleID`: Provide a value that is different than the ID supplied earlier for the `BaseDetection` key.
   * `AnalysisType`: Indicate whether this is a `rule`, `scheduled_rule`, or `policy`.
     * Currently, only rules are supported.
3. Add the metadata fields you would like to override, and their new values.
   * See the [Limitations](#limitations-of-detection-derivation) section for a list of available override fields.
   * It's possible to use the [dynamic alert fields outlined here](https://docs.panther.com/detections/writing-simple-detections#dynamic-alert-keys-in-simple-detections).
4. Upload your detection using the [`panther_analysis_tool upload`](https://docs.panther.com/panther-developer-workflows/detections-repo/pat/pat-commands#upload-uploading-packages-to-panther-directly) command.
   * It's recommended to [automatically disable Base Detections](#automatically-disabling-base-detections-in-the-cli-workflow).

**CLI workflow example**

Below is an example of a Python Base Detection ([a standard detection in the panther-analysis repository](https://github.com/panther-labs/panther-analysis/blob/main/rules/auth0_rules/auth0_mfa_policy_enabled.yml)), and below it, its Derived Detection.

```yaml
# Base Detection
AnalysisType: rule
Description: An Auth0 User enabled MFA Policy for your organization's tenant.
DisplayName: "Auth0 MFA Policy Enabled"
Enabled: True
Filename: auth0_mfa_policy_enabled.py
Runbook: Assess if this was done by the user for a valid business reason and was expected. This alert indicates a setting change that aligns with best security practices, follow-up may be unnecessary.
Severity: Medium
DedupPeriodMinutes: 60
LogTypes:
    - Auth0.Events
RuleID: "Auth0.MFA.Policy.Enabled"
Threshold: 1
Tests:
    - ExpectedResult: True
      Log:
        data:
            client_id: 1HXWWGKk1Zj3JF8GvMrnCSirccDs4qvr
            client_name: ""
            date: "2023-05-16 17:26:16.782000000"
            description: Set the Multi-factor Authentication policies
            details:
                request:
                    auth:
                        credentials:
                            jti: 0107c849078d8d889af711840197ba7c
                            scopes:
                                - create:actions
                                - create:actions_log_sessions
                                # shortened for brevity
                        strategy: jwt
                        user:
                            email: user.name@yourcompany.io
                            name: User Name
                            user_id: google-oauth2|105261262156475850461
                    body:
                        - all-applications
                    channel: https://manage.auth0.com/
                    ip: 12.12.12.12
                    method: put
                    path: /api/v2/guardian/policies
                    query: {}
                    userAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
                response:
                    body:
                        - all-applications
                    statusCode: 200
            ip: 12.12.12.12
            log_id: "90020230515215719063964000000000000001223372037488829643"
            type: sapi
            user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
            user_id: google-oauth2|105261262156475850461
        log_id: "90020230515215719063964000000000000001223372037488829643"
        p_any_ip_addresses:
            - 12.12.12.12
        p_any_usernames:
            - google-oauth2|105261262156475850461
        p_event_time: "2023-05-16 17:26:16.782"
        p_log_type: Auth0.Events
        p_parse_time: "2023-05-16 17:28:28.572"
        p_row_id: 2660c447622fa4c3dbb08f9918979102
        p_schema_version: 0
        p_source_id: b9031579-b2c5-45c2-b15c-632b995a4e36
        p_source_label: Org Auth0 Tenant Label
      Name: MFA Policy Enabled First
```

```yaml
# Derived Detection

# Required fields
AnalysisType: rule
RuleID: "Auth0.MFA.Policy.Enabled.Custom.Severity"
BaseDetection: "Auth0.MFA.Policy.Enabled"

# Fields being overwritten (i.e., overriding the default values inherited from the Base Detection)
DisplayName: "Auth0 MFA Policy Enabled - Severity Critical"
Enabled: True
Severity: Critical
Description: An Auth0 User enabled MFA Policy for your organization's tenant - severity overridden to critical.
```

{% endtab %}
{% endtabs %}

## How to view all Derived Detections

To view all Derived Detections in your Panther instance:

1. In the left-hand navigation bar of your Panther Console, click **Detections**.
2. Click **Filters** icon.\
   ![](https://4011785613-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LgdiSWdyJcXPahGi9Rs-2910905616%2Fuploads%2Fgit-blob-32af1a963a2a7704ebb1c8b50559712de6f99dfc%2Fimage.png?alt=media)
3. In the **Detection Types** dropdown field, select **Derived Rule**.
4. Click **Apply Filters**.

## Limitations of detection derivation

* Derivation is not available for [Scheduled Rules](https://docs.panther.com/detections/rules) or [Policies](https://docs.panther.com/detections/policies).
* Only one level of derivation is possible, i.e. a Derived Detection cannot be derived *from.*
* In the Console workflow, tests are inherited when the Derived Detection is created, but not thereafter when the Base Detection's tests are updated.
* If, in a Python Base Detection, the value of a metadata field is set using a Python function, that value will take precedence over an equivalent static override value supplied in a Derived Detection. For example, if a Python [`severity()`](https://docs.panther.com/detections/python#severity) function is present in the Base Detection, its value will take precedence over the Derived Detection's override value supplied in the `Severity` YAML key (in the CLI workflow) or the **Severity** field (in the Console).
  * See a full list of the Python functions that set metadata values (called "Alert functions"), as well as which fields in YAML/the Console they override, in the [Alert functions in Python detections](https://docs.panther.com/detections/python#alert-functions-in-python-detections) table.
  * It *is* possible to overwrite values set by certain Python alert functions by using [dynamic alert keys](https://docs.panther.com/detections/writing-simple-detections#dynamic-alert-keys-in-simple-detections) in your Derived Detection. For example, you can override the value of your Python Base Detection's [`severity()`](https://docs.panther.com/detections/python#severity) function in your Derived Detection by using the [`DynamicSeverities`](https://docs.panther.com/detections/writing-simple-detections#dynamicseverities) field.
    * [`DynamicSeverities`](https://docs.panther.com/detections/writing-simple-detections#dynamicseverities) overrides [`severity()`](https://docs.panther.com/detections/python#severity)
    * [`AlertTitle`](https://docs.panther.com/detections/writing-simple-detections#alerttitle) overrides [`title()`](https://docs.panther.com/detections/python#title)
    * [`AlertContext`](https://docs.panther.com/detections/writing-simple-detections#alertcontext) overrides [`alert_context()`](https://docs.panther.com/detections/python#alert_context)
    * [`GroupBy`](https://docs.panther.com/detections/writing-simple-detections#groupby) overrides [`dedup()`](https://docs.panther.com/detections/python#dedup)
* If you are creating a Derived Detection in the Console workflow and the Base Detection is a Python detection, you cannot set any alert fields dynamically—they may only be set statically.
  * It *is* possible to dynamically set alert fields in the Console workflow if the Base Detection is a Simple detection.
  * It *is* possible to dynamically set alert fields in the CLI workflow (using [`AlertTitle`](https://docs.panther.com/detections/writing-simple-detections#alerttitle), [`DynamicSeverities`](https://docs.panther.com/detections/writing-simple-detections#groupby), [`AlertContext`](https://docs.panther.com/detections/writing-simple-detections#alertcontext), and [`GroupBy`](https://docs.panther.com/detections/writing-simple-detections#groupby)) regardless of whether the Base Detection is a Python or YAML detection.
* Currently, only the below fields can be overwritten. These are YAML field names, applicable to the CLI workflow—for those with equivalent fields in the Console, those Console fields may also be overwritten.
  * `Enabled`
  * `Severity`
  * `Description`
  * `CreateAlert`
  * `DedupPeriodMinutes`
  * `InlineFilters`
  * `DisplayName`
  * `OnlyUseBaseRiskScore`
  * `OutputIds`
  * `Reference`
  * `Runbook`
  * `SummaryAttributes`
  * `Threshold`
  * `Tags`
  * `Reports`
  * `DynamicSeverities`
  * `AlertTitle`
  * `AlertContext`
  * `GroupBy`
  * `Tests`
