Jinja2 - References

On this page we will walk you through some of the references available within InsightCloudSec to use when configuring your Jinja2 templates.

The content on this page includes:

  • Resource Attributes
  • Resource Functions
  • Using BotFactory Events with Jinja
  • Example Jinja Templates
  • Advanced templates for AWS bucket policies

For assistance with any of the examples or content on this page reach out to us through the Customer Support Portal.

Testing Jinja2 Code

You can test your Jinja code prior to running a Bot using the Preview message link located in the Actions section of the Bot Creation form.

Jinja2 Commands

Some Jinja2 commands may not work correctly until the Bot has deployed.

Resource Attributes

Available attributes vary based on the resource type (e.g. instances). A list of available attributes based on the resource type can be found through each category page, as follows:

Finding a Specific Resource

We suggest navigating to the appropriate category page (e.g. Compute, Storage, etc.) and locating the individual resource. These are listed in the contents for each page on the right and can be accessed via that in-page Table of Contents, or by using a basic search on the page (e.g. CMD + F).

Using Resource Attributes

When using these actions, access resource properties by using the following syntax:

{{resource.<attribute>}}

Resource Common Data

For certain resources, the attribute details must be expressed in a slightly different format. Within InsightCloudSec there are a handful of resources that share what we refer to as common data and they are identified as such within our database.

To include these attributes you can access the properties of these specific resources with the following syntax:

{{resource.common.<attribute>}}

This syntax applies to ONLY the following:

text
1
"resource_id",
2
"name",
3
"resource_type",
4
"organization_service_id",
5
"region_name",
6
"creation_timestamp",
7
"discovered_timestamp",
8
"modified_timestamp",
9
"namespace_id"

Example of common Jinja2 command

jinja2
1
Resource type: {{resource.common.resource_type}}
2
Creation timestamp: {{resource.common.creation_timestamp}}
3
4
Note: Any formatting that applies to DATETIME fields can also be applied to resource common data date fields ("creation_timestamp", "discovered_timestamp", "modified_timestamp"), e.g., epoch format:
5
Creation Timestamp: {{resource.common.creation_timestamp.strftime('%s')}}
6
7
8

Resource External Data

Accessing external data also requires a different format, as it directly references the external data parameters harvested by InsightCloudSec.

To include these external data parameters for a given resource ID, use the following syntax:

jinja2
1
{{resource.get_resource_id()}}
2
{{resource.ext.<parameter>}}

The <parameter> reference should be substituted with any of the named parameters found within a defined external data source. See Get Data Sources for more information.

**Example of external data Jinja2 command **

jinja2
1
Cloud Account ID: {{resource.get_organization_service().account_id}}

Resource Functions

In addition to resource attributes InsightCloudSec includes support for some resource functions. Since our platform supports hundreds of resources if you are interested in a resource function or configuration that you do not see listed here reach out to our team through the Customer Support Portal.

When using these actions, you can access resource properties by using the following syntax:
{{resource.<function>}}

Each of the resource functions below (listed alphabetically) provides a high-level explanation of the capability and the associated template element(s).

Create Network Flowlog

We have added Jinja2 field supports to the Bot action, Create Network Flow Log. This capability allows you to dynamically assign S3, S3 folder, and/or Cloudwatch Logs based upon related properties (e.g. a badge of the resource’s cloud, the region of the resource, and/or the name of the resource.)

For example, this Jinja2 will create a flow log targeted at a standard S3 bucket for flowlogs by account and region and use a different folder defined by network ID.

jinja2
1
arn:aws:s3:::aws-networkflowlogs-{{resource.get_organization_service().account_id}}-{{resource.common.region_name}}/{{resource.common.provider_id}}/

Get Access Key Info

You can include this resource function in a Bot configuration for the Cloud User Resource Type. Doing so will retrieve information about the API access keys including the key ID, key status, create date, last used date, and age in days for any users included within the Bot scope.

{{resource.get_access_key_info()}}

For example:

jinja2
1
{
2
"access_key_id": "AKIA3ABCDEFGHIJLLMNOP",
3
"status": "active",
4
"create_date": "2019-10-29 20:31:40",
5
"last_used_date": "2019-11-20 22:05:00",
6
"age_in_days": 266
7
}

Get Age in Days

Allows you to retrieve information about the age of a resource in days and is applicable in any context where a date field is available. The create_date can be specified or will be assumed by default. Alternatively you can specify other dates fields, e.g. last_used_date, as a parameter.

Date fields are included in the attributes throughout our Resources documentation for each individual resource. For example, API Access Key details are here.

{{resource.get_age_in_days()}}

This template can also provide the number of days since a Cloud User's password has been used, as follows:

{{resource.get_age_in_days('password_last_used')}}

Get Attached Instance Name

The following {{resource.get_attached_instance_name()}} allows you to pull the name of the attached compute(EC2) instance/NAT gateway on Public IP resources.

Get Badge Value by Key for Parent Cloud

This new function is specific to our Microsoft Teams Integration and enables users to include dynamic details based on a particular badge key. By defining a Badge for Teams, users are able to identify multiple channels to target for messaging using a single Bot action.Previously users would be required to create a single Bot action for each Teams channel using an individual webhook).

{{resource.get_badge_value_by_key_for_parent_cloud()}}

For example, where ‘Teams’ is your badge key:

{{resource.get_badge_value_by_key_for_parent_cloud('Teams')}}

In addition users can choose to specify case sensitivity and to return a default value with the following:

  • Specify case sensitivity case_insensitive
    • Note that if not specified this value defaults to false
  • Return a default value default_return_str

For example, where case insensitivity is set to True and the default string is No Badge Found:
{{resource.get_badge_value_by_key_for_parent_cloud('Teams', case_insensitive=True, default_return_str='No Badge Found')}} .

Get Cloud Organization Details

The following "getters" can be used in Bot notification to enrich notifications:

  • resource.get_cloud_organization_id() - Retrieves the cloud specific organization ID that's defined at the top level.

  • resource.get_cloud_organization_nickname() - Retrieves the human readable nickname that's associated with the Organization within InsightCloudSec.

Get Cloud Type

To return the cloud type (AWS, Azure, GCP, etc.), use the function below:

{{resource.get_cloud_type().id}}

Get Daily Cost

Calculate the daily cost for the resource in question. If the resource does not support cost calculation then this function will return None.

{{resource.get_daily_cost()}}

In addition, use the function below to round up and limit cost value to 2 decimal places.
For example:

  • Cost with limiting 2 decimals: $2.23
  • Cost without limiting decimals: $2.2272

{{"{0:.2F}". format(resource.get_daily_cost())}}

Get Data Collection Value

This template retrieves the description for a specific data collection value.

{{resource.get_data_collection_value(collection_name='<data_collection_name>', key='<data_collection_value>')}}

For example, the following template would return the description for the value mv_1 inside the my_dc data collection: {{resource.get_data_collection_value('my_dc', key='mv_1')}}

Get Date, Timestamp, and Datetime

Calculate the date, timestamp, or datetime for a given event. These functions, in combination with a tagging strategy, can be used to provide context such as indicating when a resource was tagged with time-relevant keys, e.g. "Owner notified of impending delete", "30 day exemption granted", etc.

  • {{event.get_date()}}
  • {{event.get_date().today()}}
  • {{event.get_timestamp()}}
  • {{event.get_timestamp().utcnow()}}
  • {{event.get_unix_epoch_timestamp()}}
  • {{event.get_date(days=30)}}
  • {{event.get_timestamp(unit="minutes", value=60)}}
  • {{event.get_timestamp(unit="hours", value=12)}}
  • {{event.get_timestamp(unit="days", value=7)}}

In addition, the Filters Resource Tag Date Comparison and Resource Tag Date/Time Comparison, allow you to inspect those tags and make decisions based upon them, e.g. sending notifications, shutting down instances, deleting roles, etc.

Get Dependency IDs

Include the provider IDs of associated dependencies for a resource.

{{resource.get_dependency_ids()}}

Additionally, you can specify what type of resource as a dependency you want to list. For example, a bot scoped to Instances can have multiple dependencies (eg. Volumes, Networks, Subnets, etc). Use the syntax below to only list the Security Groups (or Access Lists).

{{resource.get_dependency_ids(resource_types=['resourceaccesslist'])}}

Get Impacted Resources

Include an optional tag key in the get_impacted_resources() to enrich the response with the value of the supplied tag. This enhancement applies to the following resource types:

  • AWS Trusted Advisor
  • AWS GuardDuty

These fields can be used when a Bot is linked to an Insight. For example, a Bot flagging a resource can share the {{event.bot_insight_name}} field to identify the specific Insight a resource is failing and to help the user more easily remedy the issue or add an exemption.

Get Last Event

This is a function that allows Bot authors to gain access to properties of the last eventof any type (from EDH) to further enrich Bot notification alerts. The syntax examples below allow you to obtain details from the last event object as follows:

  • User - {{resource.get_last_event().get('user')}}
  • User ARN - {{resource.get_last_event().get('user_arn')}}
  • Action - {{resource.get_last_event().get('action')}}
  • Timestamp - {{resource.get_last_event().get('timestamp')}}
  • IP - {{resource.get_last_event().get('ip')}}
  • Event ID - {{resource.get_last_event().get('event_id')}}
  • Event Tags - {{resource.get_last_event('tags')}}
  • Event Created - {{resource.get_last_event('create')}}
  • Event Modify - {{resource.get_last_event('modify')}}

To obtain the last suspicious event for a given resource, this function can be applied as follows: {{resource.get_last_event(None,True).get('user_arn')}}.

Get Linked Insight

This function allows Bot authors to gain access to the Insight linked to the Bot.

{{event.insight_link}}

Get Missing Permissions

Use this option as part of Bot automation to help identify and remediate cloud accounts with missing IAM permissions that impair InsightCloudSec visibility. This can be used alongside the Query Filter Cloud Account With Impaired Visibility.

{{resource.get_missing_permissions()}}

Get Monthly Cost

Calculate the monthly cost for the resource in question. If the resource does not support cost calculation then this function will return None.

{{resource.get_monthly_cost()}}

In addition, use the function below to round up and limit cost value to 2 decimal places.
For example:

  • Cost with limiting 2 decimals: $2.23
  • Cost without limiting decimals: $2.2272

{{"{0:.2F}". format(resource.get_monthly_cost())}}

Get Organization Service Name and Account ID

These walk the resource to the parent organization service (cloud account) to retrieve the name and account number assigned to the account (e.g. Acmecorp AWS Production and 123456789012).

{{resource.get_organization_service_name()}}

{{resource.get_organization_service().account_id}}

In addition, use the account_id attribute in conjunction with the "Enable Storage Container Logging" Bot Action to enable logging to buckets in each region and account (provided they follow a standard naming convention):

ics-target-bucket-{{resource.common.region_name}}-{{resource.get_organization_service().account_id}}

Get Owner Name

In InsightCloudSec you can assign ownership to resources. Doing this grants the owner full permission to that resource, and designates a point of contact (POC) for questions about the resource. This function will return the name of the POC if one is assigned, and None if one is not.

{{resource.get_owner_name()}}

Another Example Using get_owner_name

{{resource.get_owner_name()}}@rapid7.com;{{resource.common.resource_type}}@rapid7.com

In this example a customer may have an alias for all S3 buckets. The buckets can be set up with a tag owner_email, and a Bot can be set up with condition on that tag key being present, and use the delayed email action with Jinja recipient, set to: {{resource.get_tag_value('owner_email', True, '')}}

Capture the provider link to create a notification (for Slack or other services) and share a direct link for the applicable resource in the provider console. (Currently only available for specific resources, contact us via Getting Support with any questions.)

{{resource.get_provider_link()}}.

An example of this notification type is:

Get Provider Link Output Example

Get Resource Age

This field {{resource.get_age_in_days()}} allows you to retrieve the age of a resource. Including resource age information can provide meaningful context and allow users to generate notifications or take actions based upon a resource's age, e.g. rotating API keys once their age exceeds a user-defined threshold.

Get Resource CVEs

Provides a summary report of CVEs associated with the resource in question; currently valid for container images and container instances.

  • {{resource.get_resource_cves()}}

You can also limit CVEs to specific severities by including arguments:

  • {{resource.get_resource_cves(severities=['CRITICAL', 'HIGH'])}}

Get Resource Data

All

To return all the details about a resource, use the 'serialize' Jinja2 attribute shown below. Note that this can be used across all resource types, making it useful for bots that are scoped to more than one resource type.

{{resource.serialize(indent=2)}}

Example output:

jinja2
1
{
2
"common": {
3
"resource_id": "instance...",
4
"resource_name": "Cloud_Account_Name",
5
"resource_type": "instance",
6
"cloud": "AWS",
7
"account": "Cloud_Account_Name",
8
"account_id": "...",
9
"account_status": "DEFAULT",
10
"organization_service_id": 1,
11
"availability_zone": "us-east-1a",
12
"region": "us-east-1",
13
"creation_timestamp": "2021-09-08 14:19:23",
14
"discovered_timestamp": "2021-09-07 13:30:47",
15
"modified_timestamp": "2021-09-16 16:16:50",
16
"namespace_id": "arn:aws:ec2:us-east-1:...",
17
"tags": {
18
"Name": "Cloud_Account_Name",
19
"Environment": "Development"
20
}
21
},
22
"instance_id": "i-...",
23
"instance_type": "t2.xlarge",
24
"launch_time": "2021-09-08T14:19:23Z",
25
"platform": "linux",
26
"state": "running",
27
"root_device_type": "ebs",
28
"key_name": "Key-Pair",
29
"image_id": "ami-...",
30
"private_ip_address": "123.123.123.123",
31
"public_ip_address": "123.123.123.123",
32
"tenancy": "default",
33
"network_resource_id": "privatenetwork...",
34
"subnet_resource_id": "privatesubnet...",
35
"detailed_monitoring": false,
36
"role_name": "InsightCloudSec-Power-User-Role",
37
"role_resource_id": "servicerole:...",
38
"aws_instance_metadata_service_v2_required": false,
39
"aws_instance_metadata_service_hop_limit": 1,
40
"aws_instance_metadata_service_endpoint_enabled": "enabled",
41
"aws_instance_metadata_service_endpoint_config_status": "applied",
42
"architecture": "x86_64",
43
"state_transition_reason": ""
44
}

Partial - Using a JMESPath Query

InsightCloudSec has added support for a JMESPath query to resource.serialize, this allows you to:

  • Access any field available on the serialized object
  • Compose new JSON objects with the exact data and shape required

To use this feature you must pass a JMESPath expression as jmespath argument to resource.serialize.

Some examples using this capability are below:

Get All Resource Tags

text
1
{{resource.serialize(indent=2, jmespath="common.tags")}}
2
3
{
4
"Name": "Cloud_Account_Name",
5
"Environment": "Development"
6
}

Create a JSON Object with resource_id and tag values

text
1
{{resource.serialize(indent=2, jmespath="{ResourceId: common.resource_id, TagValues: values(common.tags)}")}}
2
3
{
4
"ResourceId": "instance:1:us-east-1:i-0981d16c001ec0300:",
5
"TagValues": [
6
"Cloud_Account_Name",
7
"Development"
8
]
9
}

Create a JSON Object with account_id, instance_id, and environments from tags

text
1
{{resource.serialize(indent=2, jmespath="{AccountId: common.account_id, InstanceId: instance_id, Environment: common.tags.Environment}")}}
2
3
{
4
"AccountId": "880056758000",
5
"InstanceId": "i-0981d16c001ec0300",
6
"Environment": "Development"
7
}

Get Resource Name

This walks the resource to the database object and returns the name. For resources which do not have a name, the primary key value is returned. With public IP addresses, for example, the resource’s IP address will be returned.

{{resource.get_resource_name()}}

This also works well with Bot actions that update S3 bucket policies, which require unique IDs, by using the bucket name, which is unique by definition. S3 bucket bot actions include object encryption and IP lockdown.

Get Tags from Cloud User via API Access Keys

You can include this resource function in a Bot configuration for the API Access Key Resource Type. Doing so will retrieve tag value(s) from the Cloud User using the API Access Key.

Input the tag key you're trying to retrieve the value for by replacing the key_here field, as shown in the example below:

{{resource.user.get_resource().get_tag_value(tag_key="key_here", case_insensitive=True)}}

Note

This function will only work with Users and is not applicable to any parent resource.

Get Tag Value

Get the value of a particular tag key. Only the tag key is required; however, you can optionally set the case_insensitive and default_return_str kwargs to force case sensitivity and/or return a specific value if the tag key does not exist.

{{resource.get_tag_value("tag_key", case_insensitive=True, default_return_str="None")}}

A tag key can be combined with the walk_parent_resource_group parameter to return any resources tagged with the provided key, and when those resources do not have the provided tag key, check to see if the resource's Resource Group does. If the Resource Group does, that tag value will be returned instead. For example, with a key of "Owner":

{{resource.get_tag_value(tag_key="Owner", walk_parent_resource_group=True)}}

Get Threat Finding Details

Returns a list of threat finding JSON blocks for AWS GuardDuty findings matching the following response syntax:

{{resource.get_threat_finding_details()}}

To pretty-print the JSON output:

{{resource.get_threat_finding_details(json_format=true)}}

Get Users

Currently only applicable to Secure File Transfer.

Provides information pertaining to users authorized to SSH into target server, to include user_name, public_keys, key_id, date_imported, and home_directory_type for each authorized user on the server.

{{resource.get_users()}}

Get Users Based on Credential Age

Identifies users whose server credentials are older than a given threshold, where n is the number of days.

  • {{resource.get_users_based_on_credential_age(threshold=n)}}

When used in conjunction with the Transfer Server User Credential Threshold Filter, you can identify any users with expired credentials who are also associated with a given server.

Get Vulnerabilities

Enables the return of vulnerability findings for more robust tickets, Slack messages, and alerts. Input the following syntax to return all vulnerability findings for a given resource:

{{resource.get_vulnerabilities()}}

The example below loops over all the vulnerabilities on a resource to export information about the vulnerabilities:

1
{% for vulnerability in resource.get_vulnerabilities() %}
2
{{ vulnerability.cve_id }} - {{ vulnerability.severity }} – {{ vulnerability.title }}
3
{% endfor %}

Using BotFactory Events with Jinja

To include Bot information on the Jinja output, use the following syntax:

text
1
{{event.bot_<parameter>}}
2
{{event.<parameter>}}

Get Insight Information

Insight ID - {{event.bot_insight_id}} Insight Name - {{event.bot_insight_name}}
Insight Severity - {{event.bot_insight_severity}}

These fields can be used when a Bot is linked to an Insight. For example, a Bot flagging a resource can share the {{event.bot_insight_name}} field to identify the specific Insight a resource is failing and to help the user more easily remedy the issue or add an exemption.

Get Bot Information

Bot Name - {{event.bot_name}} Bot ID - {{event.bot_id}}
Bot Link - {{event.direct_link}}
Bot Severity - {{event.bot_severity}}
Bot Description - {{event.bot_description}}
Bot Timestamp - {{event.timestamp}}

Example output:

Example Bot Output

Example Jinja Templates

Included below are several examples of dynamic messages that can be used in emails, Slack, and other messaging tools.

The title provides an explanation of their use case and includes the appropriate resource attributes and formatting. They can be copied and applied to any Bot you'd like to create.

To copy the message simply hover over the text to trigger the copy function and apply the pre-constructed template to your Bot.

Resource Is Exposed To Public

jinja2
1
This `{{resource.get_organization_service().cloud_type_id}}` storage `{{resource.get_resource_name()}}` was made public, its located in `{{resource.region_name}}`
2
3
It belongs to:
4
Cloud account `{{resource. get_organization_service_name()}}`
5
Account ID `{{resource.get_organization_service().account_id}}`
6
7
Resource type `{{resource.common.resource_type}}`

Instance in Unapproved Region

jinja2
1
An instance has been created in the unapproved region:`{{resource.common.region_name}}`
2
Instance Name: `{{resource.name}}`
3
Instance ID: `{{resource.instance_id}}`
4
Instance Launch Time: `{{resource.launch_time}}`
5
6
Instance Details:
7
{{resource.serialize(indent=2)}}

Ensure Tag Strategy is Enforced

jinja2
1
A resource of type {{resource.get_resource_type()}} was discovered at
2
{{resource.common.creation_timestamp}} without the required *owner*
3
or *contact-email* tags. The resource name is `{{resource.get_resource_name()}}`.
4
It lives in account `{{resource.get_organization_service_name()}}`.

Instance Has More Than 4 Cores

jinja2
1
`{{resource.name}}` has been created or discovered with more than 4 cores.
2
This resource will cost `${{resource.get_daily_cost()}}`/day.
3
The details are `{{resource.serialize(indent=2)}}`.
4
If this instance isn't downsized or cleaned up,
5
it will be deleted within 6 hours.

A Resource You Own Was Removed

jinja2
1
The resource `{{resource.name}}` which belongs to you, has been deleted.
2
Details below: `{{resource.serialize(indent=2)}}`

Instance With Public IP Has SSH Open To The World

jinja2
1
Instance `{{resource.instance_id}}` is `{{resource.state}}` and has a
2
public IP address of `{{resource.public_ip_address}}`. This instance has exposed
3
port 22 (SSH) open to the world. This instance is not within our security policy. Please
4
lock down the attached ACLs `{{resource.get_dependency_ids(resource_types=['resourceaccesslist'])}}`, or this instance will be
5
deleted in 4 hours.

Bad ACL

jinja2
1
Bad ACL found on `{{resource.name}}`. Please login to investigate!

Expensive Instance was created or discovered

jinja2
1
A very expensive instance `{{resource.get_resource_name()}}` created at
2
`{{resource.common.creation_timestamp}}` was found in account
3
`{{resource. get_organization_service_name()}}` which costs
4
`${{resource.get_daily_cost()}}/day` and `${{resource.get_monthly_cost()}}/mo`.

Database Open to the World

jinja2
1
An insecure database was identified with access open to the World.
2
The details of this resource are:
3
`{{resource.serialize(indent=2)}}`.

Storage Container Public Access

jinja2
1
An insecure storage container was identified with public permissions to the world.
2
The details of this resource are:
3
`{{resource.serialize(indent=2)}}`.
4
The resource has the following tags
5
`{{resource.serialize_tags(indent=2)}}`
6
This storage container is scheduled for deletion in 24 hours.
7
Please update security access rules to avoid the scheduled deletion.

CloudWatch Alarm has triggered

jinja2
1
A CloudWatch Alarm has triggered. The data on the alarm is:
2
ID of the parent organization service (cloud): `{{resource.organization_service_id}}`
3
ID of alarm: `{{resource. alarm_id}}`
4
Name of Alarm: `{{resource.name}}`
5
ARN for the account where this alarm resides: `{{resource.common.provider_id}}`
6
An optional, brief description of this alarm: `{{resource.description}}`
7
Namespace (container for CloudWatch metrics) of the alarm: `{{resource.namespace}}`
8
Name of the metric this alarm checks for: `{{resource.metric_name}}`
9
User defined threshold for this alarm: `{{resource.threshold}}`
10
Amount of times this data will be evaluated before arriving at conclusion for alarm: `{{resource.evaluation_periods}}`
11
Alarm Type: `{{resource.state_value}}`
12
Alarm Reason: `{{resource.state_reason}}`
13
More data regarding this alarm: `{{resource.state_reason_data}}`

Database Instance has had Zero Connections in 14 days

jinja2
1
Database instance `{{resource.name}}` has had no connections within 14 days. This database instance
2
resides in `{{resource.get_organization_service_name()}}` account and has an endpoint of
3
`{{resource.endpoint_address}}`.
4
This resource will have a snapshot taken, will be stopped, and finally deleted after 7 days.

Instance Provisioned outside of AMI Whitelist

jinja2
1
'{{resource.image_id}}' has been used to provision instance `{{resource.instance_id}}`
2
in `{{resource.organization_service_name}}`. This machine image is not permitted.
3
This instance will have a snapshot taken, and be terminated immediately.

User without MFA Enabled

jinja2
1
`{{resource.get_resource_type()}}: {{resource.get_resource_name()}}` in account `{{resource. get_organization_service_name()}}` with account # `{{resource.get_organization_service().account_id}}` does not have MFA enabled.

Advanced Jinja Templates (AWS)

In addition to templating for various notifications InsightCloudSec also supports the use of Jinja2 templating to add or update S3 bucket policies. These advanced capabilities are included here as examples/references of these capabilities. If you're interested in implementing Jinja2 in a more advanced way using custom policies we recommend connecting with our team through the Customer Support Portal.

In our two examples of updating bucket policy the first demonstrates the Jinja2 template required to enforce encryption, and the second is to restrict access.

Bucket Encryption Policy

If you would like to enforce encryption via bucket policy, you can create a bot that uses the Set Container Policy action and the following template to enforce encryption.

json
1
{
2
"Version": "2012-10-17",
3
"Id": "bucketpolicyid:{{event.resource.get_resource_name()}}",
4
"Statement": [
5
{
6
"Sid": "DenyIncorrectEncryptionHeader",
7
"Effect": "Deny",
8
"Principal": "*",
9
"Action": "s3:PutObject",
10
"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",
11
"Condition": {
12
"StringNotEquals": {
13
"s3:x-amz-server-side-encryption": "AES256"
14
}
15
}
16
},
17
{
18
"Sid": "DenyUnEncryptedObjectUploads",
19
"Effect": "Deny",
20
"Principal": "*",
21
"Action": "s3:PutObject",
22
"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",
23
"Condition": {
24
"Null": {
25
"s3:x-amz-server-side-encryption": "true"
26
}
27
}
28
}
29
]
30
}

Bucket Lockdown Policy

If you would like to restrict bucket access to certain IP ranges or block specific IP ranges, you can use Set Container Policy and the following template to lock down the bucket to those IP ranges.

json
1
{
2
"Version": "2012-10-17",
3
"Id": "bucketpolicyid:{{event.resource.get_resource_name()}}",
4
"Statement": [
5
{
6
"Sid": "IPAllow",
7
"Effect": "Allow",
8
"Principal": "*",
9
"Action": "s3:*",
10
"Resource": "arn:aws:s3:::{{event.resource.get_resource_name()}}/*",
11
"Condition": {
12
"NotIpAddress": {
13
"aws:SourceIp": "<insert IP range to block>"
14
},
15
"IpAddress": {
16
"aws:SourceIp": "<or insert IP range to allow>"
17
}
18
}
19
}
20
]
21
}