Policies
Scan and evaluate cloud infrastructure configurations
Overview
Policies are used to identify misconfigured cloud infrastructure and generate alerts for your team. Panther provides a number of already written and continuously updated Panther-managed policies.
Policies may be written as Python detections; they cannot be written as Simple Detections.
Matches on policies create compliance failures, but not signals. Compliance failures are visible:
In Data Explorer, in the
panther_cloudsecurity.publicdatabase, in thecompliance_historytableIn Search, in the Could Security database, in the Compliance History table
How to write a policy
Before you start writing a new policy, remember to check to see if there's an existing Panther-managed policy that meets your needs.
It is highly discouraged to make external API requests from within your detections in Panther. In general, detections are processed at a very high scale, and making API requests can overload receiving systems and cause your rules to exceed the 15-second runtime limit.
Policy body
The policy body must:
Be valid Python3.
Define a
policy()function that accepts oneresourceargument.Each policy takes a
resourceinput of a given resource type from the supported resources page.
Return a
boolfrom the policy function.
def policy(resource):
return TrueThe Python body should name the argument to the policy() function resource and also may do the following:
Import standard Python3 libraries
Import from the user defined
aws_globalsmoduleImport from the Panther defined
panthermoduleDefine additional helper functions as needed
Define variables and classes outside the scope of the rule function
Using the schemas in supported resources provides details on all available fields in resources. Top level keys are always present, although they may contain NoneType values.
Writing policies locally and in the Panther Console
You can write and deploy policies in the Panther Console or you can write them locally and upload them to Panther using the Panther Analysis Tool (PAT) CLI workflow:
How to write policies in the Panther Console
In the left-hand navigation bar of your Panther Console, click Detections.
In the upper-right corner, click Create New.
In the Policy tile, click Start.
On the create page, configure your policy:
Name: Enter a descriptive name for the policy.
ID (optional): Click the pen icon and enter a unique ID for your policy.
In the upper-right corner, the Enabled toggle will be set to
ONby default. If you'd like to disable the policy, flip the toggle toOFF.In the For the Following Resource Types section:
Resource Types: Select one or more resource types this policy should apply to. Leave empty to apply to all resources.
In the Detect section:
In the Policy Function text editor, write a Python
policyfunction to define your detection.For detection templates and examples, see the panther_analysis GitHub repository
In the Set Alert Fields section:
Severity: Select a severity level for the alerts triggered by this detection.
In the Optional Fields section, optionally provide values for the following fields:
Description: Enter additional context about the policy.
Runbook: Enter the procedures and operations relating to this policy.
To see examples of runbooks for built-in rules, see Alert Runbooks.
It's recommended to provide a descriptive runbook, as Panther AI alert triage will take it into consideration.
Reference: Enter an external link to more information relating to this rule.
Destination Overrides: Choose destinations to receive alerts for this detection, regardless of severity. Note that destinations can also be set dynamically, in the rule function. See Routing Order Precedence to learn more about routing precedence.
Ignore Patterns: Enter patterns to ignore.
Custom Tags: Enter custom tags to help you understand the rule at a glance (e.g.,
HIPAA.)In the Framework Mapping section:
Click Add New to enter a report.
Provide values for the following fields:
Report Key: Enter a key relevant to your report.
Report Values: Enter values for that report.
In the Test section:
In the Unit Test section, click Add New to create a test for the policy you defined in the previous step.
In the upper-right corner, click Save.
We recommend managing your local detection files in a version control system like GitHub or GitLab.
File setup
Each detection consists of:
A Python file (a file with a
.pyextension) containing your detection/audit logicA YAML or JSON specification file (a file with a
.ymlor.jsonextension) containing metadata attributes of the detection.By convention, we give this file the same name as the Python file.
Folder setup
If you group your policies into folders, each folder name must contain policies in order for them to be found during upload (using either PAT or the bulk uploader in the Console).
We recommend grouping policies into folders based on log/resource type, e.g., suricata_rules or aws_s3_policies. You can use the open source Panther Analysis repo as a reference.
Writing policies locally
Write your policy and save it (in your folder of choice) as
my_new_policy.py: def polcy(resource):def policy(resource): return resource['Region'] != 'us-east-1'Create a specification file using the template below:
AnalysisType: policy Enabled: true Filename: my_new_policy.py PolicyID: Category.Type.MoreInfo ResourceType: - Resource.Type.Here Severity: Info|Low|Medium|High|Critical DisplayName: Example Policy to Check the Format of the Spec Tags: - Tags - Go - Here Runbook: Find out who changed the spec format. Reference: https://www.link-to-info.io
See the full Python policy specification reference on Writing Python Detections for a complete list of required and optional fields.
Title of associated alerts
The order of precedence for setting the alert title for policies is the same as it is for Rules and Scheduled Rules—see the How the alert title is set section.
Ignoring specific cloud resources
It's possible to configure a policy to make exceptions for certain cloud resources, meaning the policy will not be run over those resources and alerts will not be generated. This is sometimes referred to as a "policy suppression."
There are three ways to configure a policy suppression:
If you are configuring a Panther-managed policy suppression, it is not reversible.
To configure a policy to ignore a resource from the resource's page in the Panther Console:
In the left-hand navigation bar of your Panther Console, click Cloud Resources.
Click the name of the cloud resource you'd like to ignore.
In the Policies section, which contains all the policies that are applied to this resource, locate the policy you'd like to configure to ignore this resource.
On the right side of its row, click the three dots icon, then Ignore.
This edits the policy, adding to its Ignore Patterns field.

To configure a policy to ignore a resource from the policy's page in the Panther Console:
In the left-hand navigation bar of your Panther Console, click Build > Detections.
Click the name of the policy you'd like to configure a suppression for.
In the Set Alert Fields section, expand the Optional Fields dropdown.
In the Ignore Patterns field, enter the ARN of the resource(s) you want to ignore.
You can ignore multiple resources with similar ARNs using a wildcard pattern. For example, you can exclude all S3 buckets with titles starting with
pantherby enteringarn:aws:s3:::panther*.

To configure a policy to ignore a resource from the policy's local file configuration:
Open the YAML file for your policy.
Add a new field, called
Suppressionswith typearray.Learn more about this field in the Python Policy Specification Reference.
Under
Suppressions, add the resource ARN(s) you'd like to ignore as a list.You can ignore multiple resources with similar ARNs using a wildcard pattern. For example, you can exclude all S3 buckets with titles starting with
pantherby enteringarn:aws:s3:::panther*.
Example:
AnalysisType: policy
PolicyID: AWS.S3.CustomPolicy.Example
...
Suppressions:
- "arn:aws:s3:::test-bucket"
- "arn:aws:s3:::panther*"Policy Writing Best Practices
Constructing Test Resources
Manually building test cases can be prone to human error. We suggest one of the following methods:
Option 1: In the Panther Console, navigate to Investigate > Cloud Resources. Apply a filter of the resource type you intend to emulate in your test. Select a resource in your environment, and on the
Attributescard you can copy the full JSON representation of that resource by selecting copy button next to the wordroot.Option 2: Open the Panther Resources documentation, and navigate to the section for the resource you are trying to emulate. Copy the provided example resource. Paste this in to the resource editor if you're working in the web UI, or into the
Resourcefield if you are working locally. Now you can manually modify the fields relevant to your policy and the specific test case you are trying to emulate.
Option 1 is best when it is practical, as this can provide real test data for your policies. Additionally, it is often the case that you are writing/modifying a policy specifically because of an offending resource in your account. Using that exact resource's JSON representation as your test case can guarantee that similar resources will be caught by your policy in the future.
Debugging Exceptions
Debugging exceptions can be difficult, as you do not have direct access to the Python environment running the policies.
When you see a policy that is showing the state Error on a given resource, that means that the policy threw an exception. The best method for troubleshooting these errors is to use option 1 in the Constructing test resources section above and create a test case from the resource causing the exception.
Running this test case either locally or in the Panther Console should provide more context for the issue, and allow you to modify the policy to debug the exception without having to run the policy against all resources in your environment.
Note: Anything printed to stdout or stderr by your Python code will end up in CloudWatch. For SaaS/CPaaS customers, Panther engineers can see these CloudWatch logs during routine application monitoring.
Policy examples
S3 public read access
In the example below, the policy checks if an S3 bucket allows public read access:
# A list of grantees that represent public access
GRANTEES = {
'http://acs.amazonaws.com/groups/global/AuthenticatedUsers',
'http://acs.amazonaws.com/groups/global/AllUsers'
}
PERMISSIONS = {'READ'}
def policy(resource):
for grant in resource['Grants']:
if grant['Grantee']['URI'] in GRANTEES and grant[
'Permission'] in PERMISSIONS:
return False
return TrueIAM Password Policy
This example policy alerts when the password policy does not enforce a maximum password age:
def policy(resource):
if resource['MaxPasswordAge'] is None:
return False
return resource['MaxPasswordAge'] <= 90In the policy() body, returning a value of True indicates the resource is compliant and no alert should be sent. Returning a value of False indicates the resource is non-compliant.
The policy is based on an IAM Password Policy resource:
{
"AccountId": "123456789012",
"AllowUsersToChangePassword": true,
"AnyExist": true,
"ExpirePasswords": true,
"HardExpiry": null,
"MaxPasswordAge": 90,
"MinimumPasswordLength": 14,
"Name": "AWS.PasswordPolicy",
"PasswordReusePrevention": 24,
"Region": "global",
"RequireLowercaseCharacters": true,
"RequireNumbers": true,
"RequireSymbols": true,
"RequireUppercaseCharacters": true,
"ResourceId": "123456789012::AWS.PasswordPolicy",
"ResourceType": "AWS.PasswordPolicy",
"Tags": null,
"TimeCreated": null
}Reference
Last updated
Was this helpful?

