PyPanther Detections Style Guide

PyPanther 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 PyPanther Detections are stored, it's recommended to:

  • Maintain a top-level module, content, in which all of your custom Python code is stored (except for the main.py file).

    The top-level directory we are calling content/ can be named anything except src/, which is a reserved repository name in Panther.

    Within this folder, it's recommended to:

    • Store custom rule definitions in a 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
.
├── README.md
├── content
│   ├── __init__.py
│   ├── helpers
│   │   ├── __init__.py
│   │   ├── cloud.py
│   │   └── custom_log_types.py
│   ├── overrides
│   │   ├── __init__.py
│   │   ├── aws_cloudtrail.py
│   │   └── aws_guardduty.py
│   └── rules
│       ├── __init__.py
│       ├── my_custom_rule.py
│       └── my_inherited_rule.py
└── main.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)

Best practices for PyPanther Detection writing

Use filters instead of overriding rule()

If you would like to alter the logic of a Panther-managed PyPanther 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