V2 Detections Style Guide

V2 detections are in closed beta starting with Panther version 1.108. Please share any bug reports and feature requests with your Panther support team.

Repository structure recommendations

Get up and running quickly by cloning the pypanther-starter-kit repository.

In your code repository where your v2 detections are stored, it's recommended to:

  • Store custom rule definitions in a custom_rules directory

  • Store logic that makes overrides on Panther-managed rules in an overrides directory

    • It's recommended for each override file to define an apply_overrides function that's called on a rule collection in main.py

  • Store custom helpers in a helpers directory

# Recommended repository structure

.
├── LICENSE.txt
├── Makefile
├── README.md
├── helpers
│   ├── __init__.py
│   ├── cloud.py
│   └── custom_log_types.py
├── main.py
├── overrides
│   ├── __init__.py
│   ├── aws_cloudtrail.py
│   └── aws_guardduty.py
├── poetry.lock
├── pyproject.toml
└── custom_rules
    ├── __init__.py
    ├── my_custom_rule.py
    ├── my_inherited_rule.py
    └── my_validation_rule.py

main.py content recommendations

It's recommended for your main.py file to:

  • Import Panther-managed rules (which you do or don't want to make overrides on) using get_panther_rules

    • If you defined apply_overrides functions, call it on rule collections

  • Import custom rules using get_rules

# Example main.py file
import custom_rules # The module you create that contains custom rules

from pypanther import get_panther_rules, get_rules, register, LogType, Severity

from helpers.custom_log_types import CustomLogType
from overrides import aws_cloudtrail, aws_guardduty

# Load Panther-manages rules for certain log types and default severities
base_rules = get_panther_rules(
     log_types=[
         LogType.AWS_CLOUDTRAIL,
         LogType.AWS_GUARDDUTY,
         LogType.PANTHER_AUDIT,
     ],
     default_severity=[
        Severity.MEDIUM,
        Severity.HIGH,
    ],
)
# Load all local custom rules
custom_rules = get_rules(module=custom_rules)

# Apply customized overrides to out-of-the-box Panther rules for AWS Cloudtrail and Guardduty
aws_cloudtrail.apply_overrides(base_rules)
aws_guardduty.apply_overrides(base_rules)

# Register all rules
register(base_rules + custom_rules)

V2 detection writing best practices

Use filters instead of overriding rule()

If you would like to alter the logic of a Panther-managed v2 detection, it's recommended to use include/exclude filters instead of overriding the rule's rule() function. Filters are designed for this purpose—to be applied on top of existing rule logic. They are executed against each incoming event before the rule() logic, in order to determine if the rule should indeed process the event.

If you are significantly altering the rule logic, you might also consider writing a custom rule instead.

Last updated