AWS Service Control Policies (SCPs) are a key layer within the six-tier policy framework, providing policy governance across all of your accounts, and functioning as a “permissions ceiling”. They serve as the protective shield for your AWS accounts, kind of like the "protective" dome in The Simpsons Movie.
SCPs help enforce security best practices, restrict access to resources, and prevent privilege escalation across all of your AWS accounts. But managing them exclusively in the AWS Console is challenging.
The main issues we see with SCPs are that they’re difficult to manage with the context and awareness of how IAM is being used at an organization, it’s difficult to track changes to policies, they are prone to drift over time, and it’s often all too easy to misconfigure an SCP and take down production services.
In this post, we’re going to blatantly steal a few of the SCP Best Practices recommended by Scott Piper in his SCP Best Practices blog post (Thank you, Scott). We’re then going to provide you with a practical way to determine which SCP’s are “safe” to apply (But please, use your best judgment here), then we’re going to shamelessly and repeatedly plug IAMbic as a better way to manage your SCPs.
Let’s start with the plugging!
IAMbic is an open-source tool that handles the complex task of managing distributed IAM permissions and compliance guardrails across multiple cloud environments. IAMbic watches the current state of your IAM, and keeps a Git repo updated with reality. Since IAMbic templates are as-code and bi-directional, you can use them in a Git-style workflow to write changes back to the cloud. Some key benefits of using IAMbic to monitor and manage IAM are:
- Version control - Easily track changes and rollback changes between different versions of your IAM, without worrying about state
- Drift Prevention - Automatically correct out-of-band changes for your important resources
- Bi-directional - Imports your existing IAM setup without requiring you to write a single line of code. Make changes, run iambic apply, and write them back to the cloud. When you’re ready to move to a production GitOps flow, we provide all of the Github Action workflows you’ll need.
- GitOps workflow - Implement IAM and SCP changes via GitOps workflows and PR reviews for governance (See our IAMOps Philosophy docs for examples)
- Common format - Manage SCPs alongside the rest of your IAM (Including your human identities in your identity provider) in a consistent format
- Optional Management Control - IAMbic keeps Git updated with the state of your IAM, regardless of whether you’re managing any resources with IAMbic. You can choose which resources (if any) you want IAMbic to manage.
Example SCPs in IAMbic
Implementing SCPs without careful consideration can have disastrous consequences for your organization. It’s crucial to have a clear understanding of the actions being used within your organization before applying restrictions. Analyzing CloudTrail logs can provide valuable insights into which actions are safe to restrict, and identify legitimate use cases that can serve as conditional exceptions in your policies.
To aid you in the analysis of your CloudTrail logs, we provide SQL queries that can be used with Cloudtrail Lake or Athena. We recommend using Cloudtrail Lake for simplicity. However, if that’s not feasible, you can create an Athena table to query your CloudTrail S3 bucket. A prerequisite to both options is that you have enabled Organizational Cloudtrail, and all trails across all of your accounts are logging to a single S3 bucket. This script can help you create an Athena table on top of that bucket. Follow the instructions on the top of the script to install and use it, and feel free to reach out if you encounter any issues.
In the following sections, we'll explore different SCPs that enhance security within your AWS Organization, we’ll provide SQL queries to determine if the SCPs are “safe” to apply (please exercise your best judgment), and we’ll also provide the IAMbic templates for implementation.
To confirm the effectiveness of each SCP, we suggest performing a "safe" action that triggers an event. Wait for approximately 30 minutes and then execute the corresponding SQL query to verify if the action was recorded as expected in your CloudTrail logs. Remember to thoroughly examine your CloudTrail S3 bucket to ensure that all of your accounts and regions are actively logged.
When running the SQL queries, consider adjusting the search period based on your requirements. The provided queries are configured to examine the past 90 days of usage by default. If you identify legitimate usage of certain events, you may need to add conditional statements to the SCPs to allow the intended identities or avoid attaching the SCPs to specific OUs or accounts.
An example conditional statement that can be added to an SCP, which allows any role with the name admin to bypass a Deny statement specified in an SCP.
If you’re copying and pasting the SCP templates below verbatim, you will need to replace the org_id and account_id values to match your AWS Organizations management account.
Lastly, if you want to convert back-and-forth between IAMbic and AWS IAM Policy Language, check out the iambic convert command, or the Policy Converter Web UI.
Give it a go, and let us know in Slack if you run into any issues, or have additional recommendations for the queries/templates.
How to assign SCPs to targets in IAMbic
To assign SCPs to targets in IAMbic, you can either attach targets to a customer-managed SCP in the AWS console and run iambic import, or append targets to your SCP IAMbic template and apply them to the cloud using iambic apply. Here are some examples:
- Apply to Specific accounts
- Apply to Specific OUs
- Apply to the Root OU of the Organization (affects all accounts)
Deny Root Access
Using the root user for everyday tasks exposes AWS resources to potential compromise. It's a best practice to use temporary credentials provided by AWS Identity Center (SSO) or IAM roles for everyday interaction with AWS. This SCP helps you pull the root of the weed to keep your AWS garden healthy and secure.
Run this query to look for root user usage over the past 90 days.
Your results should resemble the following screenshot:
CloudTrail Lake Query
In CloudTrail Lake, this query would look like the following:
Your results should resemble the following screenshot:
This IAMbic template will manage an SCP that blocks root usage by default. Temporarily disable this SCP on the target account when there is a legitimate (and peer approved) use case for using root.
Prevent Disrupting Essential Security Services
Security services, like GuardDuty, Access Analyzer, CloudTrail, S3 Public Block Access, etc. are important for maintaining the security posture of your AWS environment. Unauthorized changes to these services can compromise your security setup.
Since there may be legitimate use cases to perform certain actions, such as updating GuardDuty detectors, you may wish to modify part of this SCP with conditional exceptions.
If you frequently modify EventBridge or GuardDuty rules, this template may not be suitable for you in its current form. To minimize the maintenance effort for legitimate updates, you might need to modify this example to exclude specific identities from making changes.
Require Usage of IMDSv2 for EC2 Instances
The Instance Metadata Service (IMDSv2) comes with additional defenses against server side request forgery (SSRF) vulnerabilities compared to IMDSv1. This policy ensures that all EC2 instances use IMDSv2.
Athena RunInstances query:
CloudTrail Lake RunInstances query:
Athena ModifyInstanceMetadata query:
Cloudtrail Lake ModifyInstanceMetadata query
Cloudtrail Lake ec2RoleDelivery query:
Deny Ability to Leave AWS Organization
This policy is used to prevent users or roles from unintentionally or maliciously removing an AWS account from your organization.
If your organization only permits the usage of specific regions or if you have regulatory and compliance requirements to store data in particular regions, this SCP effectively limits unauthorized regions and should be considered.
Update the regions in the query to match approved regions in your environment.
This query retrieves the event name, region, and source of actions performed outside the ‘us-east-1’ and ‘us-west-2’ regions within the specified timeframe.
Deny ability to make a VPC accessible from the Internet that isn’t already for specific accounts.
This SCP is useful to protect your AWS resources and data from exposure to the Internet. By denying the creation and attachment of internet gateways and the creation of VPC peering connections, you can ensure that a VPC that wasn't originally internet-accessible remains that way. This is particularly useful in sandbox or development accounts where you might want to limit exposure of your infrastructure to minimize the potential attack surface and keep development activities isolated from the public internet.
Cloudtrail Lake Query
We highly recommend performing a deeper, and more customized assessment of your environment, and creating SCPs that work for your unique situation. Rhino Security Labs released a handy list of IAM Privilege Escalations that serves as a useful reference for locking down permissions.
During my time at Netflix, our team conducted an analysis of CloudTrail using this list as a reference. We used the findings to create SCPs that aimed to prevent privilege escalations and unauthorized changes to IAM permissions.
These SCPs were designed to allow only the necessary identities to have those permissions while adding additional layers of security through tagging, identity, and organizational boundaries. As we gained more experience, we continuously refined and enhanced these SCPs to ensure better protection for our AWS resources.
Once you’re ready to migrate to a production IAMbic deployment, you can start leveraging GitOps workflows with your IAM changes. See IAMbic’s IAMOps Philosophy for more information and example workflows.
That wraps up our deep dive into SCPs! We've examined their importance, shared some IAMbic templates, and guided you through the corresponding SQL queries. Your feedback is crucial in shaping our next steps, so join us on our Slack channel and share your thoughts. Thanks for joining us on this journey, stay secure, and keep in touch!
Special Thanks to Richard Julian, Phil Hadviger, and David Behroozi for help with content and for reviewing this blog post.