Disabling Security Hub controls in a multi account environment

In this blog post, you’ll learn about an automated process for disabling or enabling selected AWS Security Hub controls across multiple accounts and multiple regions. You may already know how to disable Security Hub controls through the Security Hub console, or using the Security Hub update-standards-control API. However, these methods work on a per account and per region basis. If you want to tune your posture by disabling some controls across multiple accounts, this automated approach makes it easier.

The update Security Hub controls script provided in this post uses cross account access to disable or enable several controls across multiple accounts and multiple Regions on an ad hoc basis, without having to maintain resources in each Region. These accounts can be individual accounts where Security Hub is managed independently per account, part of a Security Hub administrator setup, or a combination of these. You will need to execute this script in newly added AWS accounts again to keep the controls status consistent for new accounts.

This blog also describes an alternative solution which automates updating Security Hub controls on a schedule for any new AWS accounts that are added, and keeps the control status in member accounts consistent with the controls status in the Security Hub administrator account. The alternate solution will only work if you use Security Hub administrator setup, and must be deployed on a per Region basis.

Why disable controls?

Security Hub generates findings from continuous checks against a set of rules from supported security standards. These checks provide a readiness score and identify specific accounts and resources that require attention.

It can be useful to turn off security checks for controls that are not relevant to your environment. Disabling irrelevant controls makes it easier to identify the important findings that you can take action on.

Reasons to disable controls

There are several reasons you may choose to disable controls:

  • Controls for unused services
  • Controls using global resources
  • Controls with compensating controls

Unused services

If you are not using the specific AWS service for which a control is enabled, you may want to disable controls that have periodic checks associated with that service.

Note: Periodic checks run automatically every 12 hours, whereas change-triggered checks run when the associated resource changes state. Change-triggered checks do not run if the associated in scope resource does not exist, so you do not have to disable controls that explicitly use change-triggered checks.

For example, SageMaker.1 is a control that has a periodic check and is part of the AWS Foundational Security Best Practices standard. If you do not use Amazon SageMaker in your environment, you can disable this check temporarily. If you disable an unused check and later start using the service in the future, you must enable the check again. You should perform regular analysis of services in use across your AWS Accounts.

Global resources

Global resources, such as AWS Identity and Access Management (IAM), generate findings in each region where you have Security Hub enabled. To focus only on meaningful findings, you can disable controls for global resources in all but one Region. You will have to align the desired region to be the same Region in AWS Config where global recording is enabled. A list of all such controls for each standard are as follows:

Compensating controls

You may want to disable a Security Hub control for which a compensating control is in place. For example, the AWS Foundational Security Best Practices control CloudTrail.5 checks to see if AWS CloudTrail is configured to send logs to Amazon CloudWatch logs. You can disable this check if you are sending CloudTrail to another destination, such as Amazon Simple Storage Service (Amazon S3) or partner tools such as a SIEM solution. Another example is CIS 3.x controls. GuardDuty can be considered a compensating control instead of CloudWatch alarms for CIS 3.1, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, and 3.14

Solution overview:

The update Security Hub controls script shown below is written in Python. It uses AWS SDK for Python (Boto3) to assume a cross account IAM role in the accounts passed in the script, and uses the update-standards-control Security Hub API to enable or disable controls. You must deploy this solution in a single AWS Region.

We will review the prerequisites in the next section to understand the requirements for successfully using this solution. We will then walk through the instructions for deploying this automation through an Amazon Elastic Compute Cloud (Amazon EC2) instance along with examples of how to use the script.

Note: You can also use your local machine (customer device) or AWS Cloudshell if you meet the prerequisites described below.

Prerequisites:

The update Security Hub controls script shown below requires:

  • An IAM role for cross-account access. You should have an IAM principal able to assume an IAM role in accounts where Security Hub controls needs to be disabled or enabled. This role should have securityhub:UpdateStandardsControl permission.

    Note: If you used the Security Hub multiaccount scripts from awslabs to enable Security Hub for multiple accounts you can use the role provided in the repository for the purpose of this blog as it has the necessary permissions.

  • AWS CLI
  • Python
  • Boto3

Update security hub controls script

Let’s review the arguments the script uses to run successfully. There are both required arguments and optional arguments:

Required arguments

–input-file
Path to a CSV file containing a list of the 12 digit AWS account IDs whose controls you want to disable or enable. If you are using Security Hub administrator account, use the list-members API to generate a list of all accounts where security hub is enabled. Store this list in a CSV file, one account ID per line.

–assume-role
Role name of the execution role in each account. This role should have the securityhub:UpdateStandardsControl permission. If you will be using the sample execution role CloudFormation provided in Part B—Execution role, the name of this role is ManageSecurityHubControlsExecutionRole.

–regions
Comma separated list of Regions to update SecurityHub controls. Do not add any spaces after each comma. Specify ALL to consider all Regions where Security Hub is available. If you list a Region where you have not enabled Security Hub, the script will skip this Region and log the failure.

–standard
Enter the standard code (AFSBP, CIS, PCIDSS).
AFSBP for AWS Foundational Security Best Practices
CIS for CIS AWS Foundations
PCIDSS for Payment Card Industry Data Security Standard (PCI DSS)

The script works with one Security Hub Standard at a time. For example, you can only disable AFSBP controls in the first run of the script. If you want to disable multiple controls across AFSBP and CIS standards you must run the script twice, once for AFSBP and once for CIS controls.

–control-id-list
Comma separated list of controls, example for CIS, enter – (1.1,1.2) or for PCIDSS enter – (PCI.AutoScaling.1,PCI.CloudTrail.4)

Do not add any spaces after each comma. Control IDs can be found from the Security Hub console: Security Standards > View results > ID column in the enabled controls table. You can also find the control IDs in the Security Hub controls documentation for each standard.

Figure 1: Sample Control IDs of PCI security standards shown in console

Figure 1: Sample Control IDs of PCI security standards shown in console

–control-action
For enabling controls use ENABLED; for disabling controls use DISABLED.

–disabled-reason
Reason for disabling the controls. This text will appear in the Security Hub console for the disabled controls, it is used to understand why the control is disabled for reviews in the future. If your script uses different reasons for disabling controls, you need to run the script multiple times, once for each disable reason. This argument is NOT required (or used) for enabling controls.

Optional arguments

-h, –help
shows the help message and exit

–profile
If this argument is not given, the default profile will be used. Use this argument to parse the named profile. The credentials in this profile should have permissions to assume the execution role in each account.

Solution deployment

We are using an Amazon EC2 instance with Amazon Linux 2 (AL2) to run this automation. We will create the instance role for the EC2 in Part A, create the execution role in Part B, and launch the EC2 instance to run the Update Security Hub controls script in Part C.

Note: For the purpose of this blog, we will be creating the EC2 instance and the instance role in the Security Hub administrator account, however this is not a requirement. If you have existing cross account roles with the necessary permissions, you can use these existing roles as well.

This role should have permission to assume (sts:AssumeRole) the execution role described in Part B.

Figure 2: Amazon EC2 Instance role assumes cross account IAM role

Figure 2: Amazon EC2 Instance role assumes cross account IAM role

A sample policy for this role is provided below. This policy limits the Security Hub controls manager EC2 role to assume only a specific execution role in the downstream accounts:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::*:role/ManageSecurityHubControlsExecutionRole" } ]
}

To create the SHControlsManagerEC2 role

  1. Navigate to the IAM console of the Security Hub administrator account. You must have permission to launch an EC2 instance in this account.
  2. Create a new policy using JSON policy editor, and name it SHAssumeRolePolicy.
  3. Copy the sample policy shown above and paste it into your new policy in the JSON editor. The resource in the policy is the execution role, as will be described in Part B—Execution role below.

    Note: If you are using an existing role as the execution role, rather than creating a new role as shown in Steps 1-4, then you will need to change the resource section of the sample code in Figure 2 to use the ARN of the existing execution role.

  4. In the IAM console, Create an IAM role for EC2 and name it SHControlsManagerEC2. Assign the following policies:
    1. The SHAssumeRolePolicy policy you created in step 2.
    2. The AmazonSSMManagedInstanceCore managed policy for managing the instance using AWS Systems Manager.
    3. The AWSSecurityHubReadOnlyAccess managed policy for allowing read only access to Security Hub.
    Figure 3: IAM policies attached to Amazon EC2 Instance role

    Figure 3: IAM policies attached to Amazon EC2 Instance role

  5. When you are finished creating the role, note the Amazon Resource Name (ARN) – you will be using it in Part B. The ARN will look like Figure 4: arn:aws:iam::111111222222:role/SHControlsManagerEC2
    Figure 4: ARN of the Amazon EC2 instance role

    Figure 4: ARN of the Amazon EC2 instance role

Part B–Execution role

The execution role must be created in all accounts where you will be disabling or enabling controls. This role should have securityhub:UpdateStandardsControl permission. The execution role trust relationship should allow the Security Hub controls manager role to assume the execution role.

Important: The name of the execution role must be identical in each account (including the Security Hub administrator account), otherwise the script will NOT work.

If you are using AWS Organizations, you can use CloudFormation StackSets to deploy this execution role easily across all of your accounts. The stack set runs across the organization at the root or organizational units (OUs) level of your choice. The CloudFormation will use the ARN you noted from Security Hub controls manager EC2 role as a parameter.

Sample execution role policy

A sample policy for the execution role is provided below:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "securityhub:UpdateStandardsControl", "Resource": "arn:aws:securityhub:*:*:hub/default" } ]
}

Sample execution role trust policy

Note: the ARN in the principal section below should be the ARN you noted in step 5 of Part A: Security Hub controls manager EC2 role.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111222222:role/SHControlsManagerEC2" }, "Action": "sts:AssumeRole" } ]
}

To launch the stack set for creating cross account IAM Roles

  1. Login to the console of the Organizations management account or CloudFormation delegated administrator account.
  2. Select StackSet and choose Create StackSet
  3. Choose template is ready, and select template source as Amazon S3 URL
  4. Enter the following URL, then click next: https://awsiammedia.s3.amazonaws.com/public/sample/1083-disabling-security-hub-controls-multi-account/aws-securityhub-updatecontrols-executionrole.yml
    Figure 5: Create a AWS CloudFormation StackSet

    Figure 5: Create a AWS CloudFormation StackSet

  5. Enter a stack name, update description as needed and then under parameters enter the ARN of the Security Hub controls manager EC2 role used in step 5 of Part A–Security Hub controls manager EC2 role, then choose Next.
    Figure 6: AWS CloudFormation StackSet parameters for creating cross account IAM role

    Figure 6: AWS CloudFormation StackSet parameters for creating cross account IAM role

  6. (Optional) On the Configure StackSet options page, go to Tags and add tags to identify and organize your stack set.
    Figure 7: Optionally define tags for the stacks created using AWS CloudFormation StackSet

    Figure 7: Optionally define tags for the stacks created using AWS CloudFormation StackSet

  7. On the Set deployment options page, select the desired Region. Since the resource being created is IAM, you will only need to specify one Region. Choose Next.
    Figure 8: Specify target regions where the CloudFormation stacks need to be created

    Figure 8: Specify target regions where the CloudFormation stacks need to be created

  8. Review the definition and select I acknowledge that AWS CloudFormation might create IAM resources. Choose Submit.
  9. You can monitor the creation of the stack set from the Operations tab to ensure that deployment is successful.

Note: StackSets does not deploy stack instances to the organization’s management account, even if the management account is in your organization or in an OU in your organization. You will need to create the execution role manually in the organization management account.

Part C–Launch EC2

We will be using a t2.micro EC2 instance with Amazon Linux 2 (AL2) image which comes preinstalled with AWS CLI and Python. This instance size and image are free tier eligible.

To launch the EC2 instance for executing securityhub-updatecontrols-script

  1. Launch EC2 instance in the Security Hub administrator account in a single Region. You can use any Region.
  2. Attach the IAM role to the instance as created in part A.
  3. Confirm instance is in a running state.
  4. Login to the instance CLI using AWS Systems Manager Session Manager. Go to the EC2 console, select the instance and choose Connect.
    Figure 9: Access newly launched Amazon EC2 instance using session manager

    Figure 9: Access newly launched Amazon EC2 instance using session manager

    Note: You will need to allow outbound internet access to systems manager endpoints for session manager to work. See session manager documentation for more information.

  5. On the next page, choose Connect again.
    Figure 10: Connect to Amazon EC2 instance

    Figure 10: Connect to Amazon EC2 instance

  6. A new window with session manager will open.
  7. Set the working directory to home directory.
     cd /home/ssm-user
  8. Install Git:
     sudo yum install git
  9. Clone the UpdateSecurityHubControls code repository.
     git clone https://github.com/aws-samples/SecurityHub-Multiaccount-UpdateControls.git
  10. Start a virtual environment.
     python3 -m venv SecurityHub-Multiaccount-UpdateControls/env source SecurityHub-Multiaccount-UpdateControls/env/bin/activate
  11. Upgrade pip and Install boto3
     pip install pip --upgrade pip install boto3

You are now ready to run the script.

Example 1–Disabling Controls

Let’s assume you have Config global recording enabled in us-east-1 and want to disable controls associated with global resources (IAM.1, IAM.2, IAM.3, IAM.4, IAM.5, IAM.6, IAM.7) for AWS Foundational Security Best Practices standard in Regions us-west-1, us-east-2 in all accounts. The name of our execution role in all accounts is ManageSecurityHubControlsExecutionRole

  1. Change to the correct directory
    $ cd SecurityHub-Multiaccount-UpdateControls
  2. Create a file with the list of account IDs. This is passed with the input-file argument.
    $ nano accounts.csv
  3. Enter account IDs one account per line, then save the file.
    Figure 11: CSV file with AWS account IDs

    Figure 11: CSV file with AWS account IDs

  4. Run the script:
     python SH-UpdateControls.py \
    --input-file accounts.csv \
    --assume-role ManageSecurityHubControlsExecutionRole \
    --regions us-east-2,us-west-1 \
    --standard AFSBP \
    --control-id-list IAM.1,IAM.2,IAM.3,IAM.4,IAM.5,IAM.6,IAM.7 \
    --control-action DISABLED \
    --disabled-reason 'Disabling IAM checks in all regions except for us-east-1, as global recording is enabled in us-east-1'
    
  5. As the script runs, it generates a summary of disabled controls. If there are failures, the reason for failures will be listed in the summary. A log file is also saved in the directory with execution logs.
    Figure 12: Execution Summary showing successful updates and failure information

    Figure 12: Execution Summary showing successful updates and failure information

Example 2–Enabling Controls

Let’s say you have disabled Control IDs PCI.CodeBuild.1 and PCI.CodeBuild.2 from the PCI standard in your accounts, as in the past, you did not use AWS CodeBuild in your PCI environment.

After a recent architecture review, you decided to begin using CodeBuild in your accounts in us-west-1, eu-west-1, ap-southeast-1. The name of our execution role in all accounts is ManageSecurityHubControlsExecutionRole.

  1. Confirm you have completed all steps in part C.
  2. Change to the correct directory.
    $ cd SecurityHub-Multiaccount-UpdateControls
  3. Create a file with the list of account IDs. This will be passed with the input-file argument.
    $ nano accounts.csv
    Enter account IDs one account per line, then save the file.
    Figure 13: CSV file with AWS account IDs

    Figure 13: CSV file with AWS account IDs

  4. Run the script to enable controls
     python SH-UpdateControls.py \
    --input-file accounts.csv \
    --assume-role ManageSecurityHubControlsExecutionRole \
    --regions us-west-1,eu-west-1,ap-southeast-1 \
    --standard PCIDSS \
    --control-id-list PCI.CodeBuild.1,PCI.CodeBuild.2 \
    --control-action ENABLED \
    
  5. As the script runs, it generates a summary of enabled controls. If there are failures the reason for failures will be listed in the summary A log file is also saved in the directory with execution logs.
    Figure 14: Execution Summary showing controls enabled

    Figure 14: Execution Summary showing controls enabled

Alternative Solution

Consider a case where new member accounts are being added to the Security Hub administrator of the organization. In such a scenario, you would have to disable the controls manually, or by re-running the update Security Hub controls script in each new account.

Figure 15: High level architecture

Figure 15: High level architecture

This alternative solution addresses this problem by automating the process with AWS Step Functions and a scheduled EventBridge event. A state machine is triggered every 24 hours, which updates the status of the standard controls in all AWS accounts registered as members in the Security Hub administrator account. This solution maintains a list of account IDs within a DynamoDB table, for which exceptions can be made. For details on how to deploy and use this solution, refer to this GitHub repository. This alternative solution and the update SecurityHub controls script are independent of each other.

Conclusion

In this blog, you learned some of the reasons you might disable Security Hub controls. We showed how the controls can quickly be disabled or enabled using the update Security Hub controls script provided. This script will save you time if you want to update controls across multiple accounts and multiple Regions on an as needed basis.

We also introduced an alternative solution which uses AWS Step Functions and a scheduled CloudWatch event to update Security Hub controls in new accounts on a regular basis. You could use either of the two solutions depending on the scenario.

If you have feedback about this post, submit comments in the Comments section below. If you have trouble with the scripts, please open an issue in GitHub.

 
If you have feedback about this post, submit comments in the Comments section below.

Want more AWS Security news? Follow us on Twitter.

Priyank Ghedia

Priyank Ghedia

Priyank is a Solutions Architect focussed on Threat Detection and Incident Response. Priyank helps customers meet their security visibility and response objectives by building architectures using AWS security services and tools. Before AWS, he spent 8 years advising customers on global networking and security operations.

Praveen Haranahalli

Praveen Haranahalli

Praveen Haranahalli is a Solutions Architect at AWS, based in Orlando, Florida. Praveen has helped a diverse set of customers to design and operate a broad variety of workloads using AWS Services and has a keen interest in Security and Governance. Outside of work, he loves being outdoor with his family.

Ahmed Bakry

Ahmed Bakry

Ahmed Bakry is a Security Consultant at AWS Professional Services and based in Amsterdam. He obtained his master’s degree in Computer Science at the University of Twente and specialized in Cyber Security. And he did his bachelor degree in Networks Engineering at the German University in Cairo. His passion is developing secure and robust applications that drive success for his customers.

Michael Fuellbier

Michael Fuellbier

Michael Fuellbier is a Security Consultant at AWS Professional Services. His passion is designing and building secure and robust applications together with his customers. He studied mathematics and has a background in penetration testing.