Custom Scripts
Custom Scripts are used with Rules and Policies to collect additional data or to respond to collected data. There are four types of Custom Scripts:
- Retrieval scripts are used by Custom Rules to collect data and return it to the Rule.
- Policy Response scripts respond to a failing Policy Test in order to remediate that test.
- Change Response scripts respond when an Element's attributes don't match the configuration specified in the Response.
- Account Login scripts enable Configuration Manager to access cloud-based Assets that are not supported Cloud Accounts.
Scripts must export a single function that takes two parameters – “params” and “context”, and returns a value or a Promise for a value. The “params” are the parameters specified for the Custom Script (defined in the Custom Script Reference). The “context” is a global object that includes variables defined at the Cloud Account level and merged with data returned by Prerequisite Rules.
For detailed information and examples of each type of Custom Script, see the Custom Script Reference.
Working with Custom Scripts

-
Navigate to Environment > Policy Management and select the Custom Scripts tab.
-
Click New.
-
In the New Custom Script dialog, complete these fields:
-
Name
-
Description
-
Type
-
-
Enter the script in the main text field using JavaScript (specifically ES2020). For details and examples of each type of Custom Script, see the Custom Script Reference.
-
To define parameters used in the script:
- Click + next to Custom Parameters.
- Enter a Name that corresponds to a parameter defined in the script.
- Complete the other fields for the parameter.
-
Click Save to save and/or debug the script. For information about debugging each type of Custom Script, see the Custom Script Reference.

Custom Scripts created by Tripwire (Author=Tripwire) are read-only and can't be edited directly, but you can duplicate them and then edit the duplicates.
- Navigate to Environment > Policy Management and select the Custom Scripts tab.
-
To edit a non-Tripwire Custom Script, select it and click Edit.
To edit a Tripwire Custom Script, select it and click Duplicate. Then select the new Custom Script and click Edit.
-
In the Edit Custom Script dialog, edit these fields if desired:
-
Name
-
Description
-
Type
-
-
Edit the script using JavaScript (specifically ES2020) or modify any of the parameters associated with it. For details and examples of each type of Custom Script, see the Custom Script Reference.
-
Click Save to save and/or debug the script.
Custom Script Reference
Retrieval Scripts
Retrieval Scripts used in Prerequisite Rules must return an object (key-value dictionary). Retrieval Scripts used in Primary Rules can return any type of value.

This Retrieval Script loops through all AWS Cloudtrails provided by a Prerequisite Rule and calls both GetTrailStatus and GetEventSelectors on each trail:
const aws = require('builtins').aws let getTrailStatus = async function(context, trailName, homeRegion) { try{ let response = await aws({ service: 'CloudTrail', method: 'GetTrailStatus', params:{'Name': trailName}, config: {region: homeRegion}}, context); return response.IsLogging } catch(e){ console.log(e) } } let getTrailEventSelectors = async function(context, trailName, homeRegion) { try{ let response = await aws({ service: 'CloudTrail', method: 'GetEventSelectors', params:{'TrailName': trailName}, config: {region: homeRegion}}, context); return response['EventSelectors'] } catch(e){ console.log(e) } } module.exports = async function(params, context) { //retrieving homeRegions for describeAlarms let TrailInfo = [] await Promise.all(context.aws_cloudtrails.map(async trail => { let isLogging = await getTrailStatus(context, trail.Name, trail.HomeRegion) let trailEventSelectors = await getTrailEventSelectors(context, trail.Name, trail.HomeRegion) let temp_trail = {...trail} temp_trail.IsLogging = isLogging temp_trail.EventSelectors = trailEventSelectors TrailInfo.push(temp_trail) })) return TrailInfo }

To debug a Retrieval Script, assign it to a "Custom" Rule and then debug the Rule from the Rule debug screen.
We recommend keeping the Custom Script and the Rule open in separate tabs to make it easier to modify the script and then execute the Rule debug action.
Policy Response Scripts
Policy Response scripts respond to a failing Policy Test to remediate that Test. These Custom Scripts can obtain the output of the failing Policy Test by accessing context.data.output.
Policy Response scripts can return any dict or list object. We recommend returning something that helps to identify more information about what occurred during the response.

This script responds to a failing Test by enabling log file validation for cloudtrails that do not have it enabled and then returning a list of cloudtrails that were remediated. You can see that the script got a list of failing trails from the failing Policy Test output via context.data.output. It loops through each one of those and executes an API call to enable log file validation.
const aws = require('builtins').aws module.exports = async function(params, context) { let failingCloudTrails = context.data.output await Promise.all(failingCloudTrails.map(async badCloudTrail => { console.info("Enabling Log File Validation For CloudTrail: ",badCloudTrail) let updateParams = { 'Name': badCloudTrail, 'EnableLogFileValidation': true } let updateKey = await aws({ service: 'CloudTrail', method: 'UpdateTrail', params: updateParams },context) })) let remediationResponse = { 'message': 'Enabled Log File Validation on CloudTrails', 'CloudTrails': failingCloudTrails } return remediationResponse }

To debug a Policy Response script:
- Assign the Policy Response script to a Policy Test.
- Scan a Cloud Account using the Policy Test to generate some results in the Cloud dashboard.
- On the Edit Custom Script page, click Debug to open the debug panel.
- In the debug panel, select the same Cloud Account you just scanned and the Policy Test that has the Custom Script specified as the response.
- In the debug panel, click Run Fix Now.
- Review the results and edit the script as necessary.
The Debug panel has the following fields:
- Last Item Result shows the last results associated with the selected Policy Test in the Debug panel.
- Test Output shows the filtered test output for the selected Policy Test and the selected Cloud Account.
- Test Result shows the pass/fail status of the selected Policy Test and the selected Cloud Account.
- Response Fix Options shows any options available for fixing a failing Policy Test. You can modify these options here before clicking the Run Fix Now button.
Change Response Scripts
Change Response scripts are specified in Inventory Rules, and they run when the results returned by an Inventory Scan don't match the configuration specified in the Response. For example, a Change Response could be associated with an Inventory Rule that checks privacy settings for S3 buckets. If a Scan using that Rule detects that a bucket is no longer private, the Response script would revert the bucket's settings to ensure that it stays private.
Change Responses work by comparing the attribute values of Elements returned by a Rule to values specified in the script. If an Element's attribute value differs from the value in the script, the Response Script will execute.

This script exposes 4 different parameters to a user for responding to an element (blockPublicAcls, ignorePublicAcls, blockPublicPolicy, and restrictPublicBuckets). You can use these parameters to specify how CM should respond to a particular Element (in this case to a particular S3 bucket). The script will modify the settings of a bucket according to the specified configuration.
module.exports = async function (params, context) { const aws = require('builtins').aws const newParams = {} if (params.blockPublicAcls !== undefined) { newParams.BlockPublicAcls = params.blockPublicAcls } if (params.ignorePublicAcls !== undefined) { newParams.IgnorePublicAcls = params.ignorePublicAcls } if (params.blockPublicPolicy !== undefined) { newParams.BlockPublicPolicy = params.blockPublicPolicy } if (params.restrictPublicBuckets !== undefined) { newParams.RestrictPublicBuckets = params.restrictPublicBuckets } if (Object.entries(newParams).length === 0) { throw new Error('No params to enforce') } const existingParams = { BlockPublicAcls: context.data.current.attributes.blockPublicAcls, IgnorePublicAcls: context.data.current.attributes.ignorePublicAcls, BlockPublicPolicy: context.data.current.attributes.blockPublicPolicy, RestrictPublicBuckets: context.data.current.attributes.restrictPublicBuckets, } console.info('Existing Public Access Block settings: ', existingParams) console.info('Public Access Block settings to enforce: ', newParams) const paramsToSet = { ...existingParams, ...newParams, } const response = await aws( { service: 'S3', method: 'PutPublicAccessBlock', params: { Bucket: context.data.current.bucketName, PublicAccessBlockConfiguration: paramsToSet, }, }, context ) return response }
Let's say you have configured a response to specify that blockPublicAcls must be true. Then CM scans an S3 bucket using a Rule with this Change Response Script and returns the following settings:
{ 'bucketName': 'bucket1', 'arn': 'bucket-arn', 'attributes': { 'blockPublicAcls': false, }, 'policyData': {'something': 'here'} }
CM compares the value of the blockPublicAcls attribute of the bucket (false), to the response value (true). Because these two values differ, the Change Response script is executed for this bucket.
The script received a "params" value of '{blockPublicAcls: true}' and receive the bucket data from the scan via "context.data.current". The script pulls the bucket name out of "context.data.current" and executes an API call to set BlockPublicAcls to true.
Account Login Scripts
Account Login scripts can be used to create "Custom" Cloud Accounts to monitor SaaS services that CM does not currently support. When you create a Cloud Account and select "Custom" as the Account Type, you can select an Account Login script that will be used to access the service.
An Account Login script is the first thing that runs during the scan process. The return value is stored under the "login" key, which can then be used by other Rules to authenticate to APIs. Custom Accounts can generally only be monitored using Custom Rules or generic Rule Types like REST.

module.exports = async (params = {}, context = {}) => { const url = 'https://login.example.com/dologin' const request = 'username=${context.username}&password=${context.secrets.password}' const response = await fetch(url, { method: 'post', body: request, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }) const data = await response.json() return { token: data.access_token } }
Rules can then use login.token as an authentication header, or whatever is needed for the API.