Package: panther-config
Panther Config SDKThe Panther Config module allows you to configure detections for yourPantherinstance.Getting StartedInstallThe Panther Config SDK can be installed using PIP.pip3installpanther-config==0.0.19Writing a detectionYou can use thedetectionmodule in Panther config to configure detections. The example below shows a detection that processing an HTTP log.Assuming we have a log typeInternal.HTTP.Trafficthat has the following shape:{"method":"POST","useSSL":false,"path":"/api/some/endpoint","host":"internal.megacorp.com"}We can write a detection to check for insecurePOSTandPUTrequests:# import the "detection" module, as we'll be creating a rule.frompanther_configimportdetection# The next four functions are used in the detection definition that follows. Panther# detections allow for parts of a detection to be defined with custom Python code.# "filter_insecure" is an example of python function that will be used to create# a detection.PythonFilter that only matches insecure events. The event argument will# have a python dict object corresponding to the JSON event.deffilter_insecure(event,params):returnevent["useSSL"]==False# "filter_http_methods" is a slightly more complicated python function that we will use# to create a detection.PythonFilter later. This function uses the second "params" argument# to make the function's logic reusable.deffilter_http_methods(event,params):allowed_methods=params["methods"]actual_method=event["method"]returnactual_methodinallowed_methods# "reference_generator" is another example where we will use some python code to dynamically# change the information Panther presents on an Alert resulting from a Detection match. In# this example, we're populating a query param with some relevant information from# the contextual event.defreference_generator(event):origin=event["origin"]returnf"https://wiki.internal.megacorp.com/hosts_db?host={origin}"# "make_context" will be used to attach arbitrary data to the resulting Alert. This# can be used to simply change how data is presented or be used to push machine readable information# to a downstream Alert Destination.defmake_context(event):# The Panther Config SDK's hooks to arbitrary python come with some restrictions. When the# detection is saved, the Panther backend will capture the source of provided function to use# in realtime log data processing and other backend processes. Because of this, functions used# to define a detection must not have references that are not local to the function body. Therefore,# imports targeting any of the below _must_ be included in the function body:##   - The python standard library#   - Libraries that are enabled on your Panther instance#   - Panther "Global Helpers" that you have configured on your instanceimportfnmatchpath=event["path"]return{"is_api_path":fnmatch.fnmatch(path,"/api/*")}# "pick_severity" is a custom function we are using to define the severity of Alerts based on# the data present in the current log. The detection.Rule declaration below shows how this method# is registered with the definition of our Rule.defpick_severity(event)->str:frompanther_configimportdetection# required. see notes in comment above "make_context"ifevent["origin"]!="internal.megacorp.com":returndetection.SeverityInforeturndetection.SeverityInfo# Declare a rule. Every call to "detection.Rule" in your repo will create a Rule in the Panther backend.# This example uses a subset of the fields available to define a Rule. See "Full Dataclass API" for# all the available fields.detection.Rule(# Give the Rule an id. This name must be unique on your Panther# instance. Dot separated names following "namespace" pattern is recommended.rule_id="Internal.HTTP.Traffic.Insecure",# Pick a human friendly name for the rule. This will be used# to present the Rule in the Panther Console UIname="Detect insecure internal HTTP traffic",# Specify one or more log types for your Rule. This setting is what# tells the Panther backend to run this Rule against the log data depicted above.log_types=["Internal.HTTP.Traffic"],# Specify an enabled state for the Rule. Detections can be uploaded in a# disabled state and will not begin processing log data until enabled.enabled=True,# Optionally, you can specify a list of tags to associate with the detection.tags=["internal"],# The "filters" list defines the sequence of matching logic that an event# will be tested against to determine whether there is a match. Returning "True" proceeds to the# next check. If the final check returns "True", there is a match.filters=[# If the HTTP transaction was secure, we're not interested in that log in this detection.# Therefore, the first filter uses the "filter_insecure" function we defined to filter to only# events that have useSSL set to "false".detection.PythonFilter(func=filter_insecure),# For now, we're only interested in getting alerted for insecure POST and PUT requests.# We therefore define the second filter step using "filter_http_methods". Unlike "filter_insecure",# we pass some parameters to this function.detection.PythonFilter(func=filter_http_methods,params={'methods':["POST","PUT"]}),],# On this line, we're defining the severity that should be associated with any resulting alerts.# We have the option of defining a static severity (simply: severity="INFO") but, in this case, we want# to make the severity dynamic based on data from the event. To do this, we reference the "pick_severity"# function we defined at the top of the file. We also provide a fallback value in case the dynamic function# cannot be processed. This fallback will also be the Severity value displayed in the Panther Console UIseverity=detection.DynamicStringField(func=pick_severity,fallback=detection.SeverityInfo,),# Below we specify the "reference" field. This optional field is used to attach a link to any Alerts# resulting from this detection. Similar to "severity" we can make this field dynamic based on# event data. There is also a fallback value specified.reference=detection.DynamicStringField(func=reference_generator,fallback="https://wiki.internal.megacorp.com/hosts_db",),# Fields like "runbook" and "description" are also available to further customize how any# resulting Alerts will be displayed. These can have dynamic handlers defined, but in this# example static string values will work just fine.runbook="Optional runbook content",description="A helpful description",# Finally, we use the optional "alert_context" field to tell the Panther backend to use our# "make_context" function to generate custom data that will be attached to any resulting Alerts.alert_context=make_context,)Full Dataclass APIdetection moduleDynamicStringFieldMake a field dynamic based on the detection inputFieldDescriptionTypefallbackFallback value in case the dynamic handler failsstrfuncDynamic handlerOptional[Callable[[PantherEvent], str]]DynamicDestinationsMake destinations dynamic based on the detection inputFieldDescriptionTypefallbackFallback value in case the dynamic handler failsOptional[List[str]]funcDynamic handlerCallable[[PantherEvent], List[str]]AlertGroupingConfiguration for how an alert is groupedFieldDescriptionTypeperiod_minutesHow long should matches be grouped into an alert after the first matchintgroup_byFunction to generate a key for grouping matchesOptional[Callable[[PantherEvent], str]]PythonFilterCreate a filter by referencing a python functionFieldDescriptionTypefuncProvide a function whose python source will be used as the filter definitionCallable[[PantherEvent], bool]UnitTestMockMock for a unit testFieldDescriptionTypenamename of the object to mockstrreturn_valuestring to assign as the return value for the mockstrJSONUnitTestUnit test with json contentFieldDescriptionTypenamename of the unit teststrexpect_matchwhether the data should match and trigger an alertbooldatajson stringstrmockslist of mocks to use in the testOptional[List[UnitTestMock]]PolicyDefine a Policy-type detection to execute against log data in your Panther instanceFieldDescriptionTypepolicy_idID for the Policystrignore_patternsPatterns of resource ids to ignore for the policyOptional[Union[str, List[str]]]destinationsAlert destinations for the policyOptional[Union[str, List[str], DynamicDestinations]]filtersDefine event filters for the policyUnion[Union[PythonFilter], List[Union[PythonFilter]]]enabledWhether the policy is enabled or notboolresource_typesWhat resource types this policy will apply toUnion[str, List[str]]severityWhat severity alerts generated from this policy get assignedUnion[str, DynamicStringField]nameWhat name to display in the UI and alerts. The PolicyID will be displayed if this field is not set.Optional[str]descriptionDescription for the policyOptional[Union[str, DynamicStringField]]referenceThe reason this policy exists, often a link to documentationOptional[Union[str, DynamicStringField]]reportsA mapping of framework or report names to values this policy covers for that frameworkOptional[Dict[str, List[str]]]runbookThe actions to be carried out if this policy fails, often a link to documentationOptional[Union[str, DynamicStringField]]tagsTags used to categorize this policyOptional[Union[str, List[str]]]unit_testsUnit tests for this policyOptional[Union[Union[JSONUnitTest], List[Union[JSONUnitTest]]]]alert_titleTitle to use in the alertOptional[Callable[[PantherEvent], str]]alert_contextOptional JSON to attach to alerts generated by this policyOptional[Callable[[PantherEvent], Dict[str, Any]]]alert_groupingConfiguration for how an alert is groupedOptional[AlertGrouping]RuleDefine a Rule-type detection to execute against log data in your Panther instanceFieldDescriptionTyperule_idID for the rulestrseveritySeverity for the ruleUnion[str, DynamicStringField]thresholdNumber of matches received before an alert is triggeredintnameDisplay name for the ruleOptional[str]log_typesLog Types to associate with this ruleUnion[str, List[str]]filtersDefine event filters for the ruleUnion[Union[PythonFilter], List[Union[PythonFilter]]]enabledWhether the rule is enabled or notboolunit_testsDefine event filters for the ruleOptional[Union[Union[JSONUnitTest], List[Union[JSONUnitTest]]]]tagsTags for the ruleOptional[Union[str, List[str]]]referenceReference for the ruleOptional[Union[str, DynamicStringField]]runbookRunbook for the ruleOptional[Union[str, DynamicStringField]]descriptionDescription for the ruleOptional[Union[str, DynamicStringField]]summary_attrsSummary Attributes for the ruleOptional[List[str]]reportsReport mappings for the ruleOptional[Dict[str, List[str]]]destinationsAlert destinations for the ruleOptional[Union[str, List[str], DynamicDestinations]]alert_titleTitle to use in the alertOptional[Callable[[PantherEvent], str]]alert_contextOptional JSON to attach to alerts generated by this ruleOptional[Callable[[PantherEvent], Dict[str, Any]]]alert_groupingConfiguration for how an alert is groupedOptional[AlertGrouping]ScheduledRuleDefine a ScheduledRule-type detection to execute against query results in your Panther instanceFieldDescriptionTyperule_idID for the scheduled rulestrseverityWhat severity alerts generated from this scheduled rule get assignedUnion[str, DynamicStringField]thresholdNumber of matches received before an alert is triggeredintnameDisplay name for the scheduled ruleOptional[str]scheduled_queriesScheduled queries to associate with this scheduled ruleUnion[str, List[str]]filtersDefine event filters for the scheduled ruleUnion[Union[PythonFilter], List[Union[PythonFilter]]]enabledShort description for the scheduled ruleboolunit_testsDefine event filters for the scheduled ruleOptional[Union[Union[JSONUnitTest], List[Union[JSONUnitTest]]]]tagsTags for the scheduled ruleOptional[Union[str, List[str]]]referenceReference for the scheduled ruleOptional[Union[str, DynamicStringField]]runbookRunbook for the scheduled ruleOptional[Union[str, DynamicStringField]]descriptionDescription for the scheduled ruleOptional[Union[str, DynamicStringField]]summary_attrsSummary Attributes for the scheduled ruleOptional[List[str]]reportsReport mappings for the scheduled ruleOptional[Dict[str, List[str]]]destinationsAlert destinations for the scheduled ruleOptional[Union[str, List[str], DynamicDestinations]]alert_titleTitle to use in the alertOptional[Callable[[PantherEvent], str]]alert_contextOptional JSON to attach to alerts generated by this ruleOptional[Callable[[PantherEvent], Dict[str, Any]]]alert_groupingConfiguration for how an alert is groupedOptional[AlertGrouping]query moduleCronScheduleCron expression based schedule definition for a queryFieldDescriptionTypeexpressionDefines how often queries using this schedule runstrtimeout_minutesDefines the timeout applied to queries with this scheduleintIntervalScheduleInterval based schedule definition for a queryFieldDescriptionTyperate_minutesDefines how often queries using this schedule runinttimeout_minutesDefines the timeout applied to queries with this scheduleintQueryA saved or scheduled queryFieldDescriptionTypenameUnique name for the querystrdescriptionShort description for the querystrdefault_databaseDefault database for the querystrsqlSQL statementstrenabledWhether the query is enabled or notbooltagsTags for the queryOptional[Union[str, List[str]]]scheduleSchedule attached to the queryOptional[Union[IntervalSchedule, CronSchedule]]