I introduced the fundamental concepts of service control policies (SCPs) in the previous post. We discussed what SCPs are, why you should create SCPs, the two approaches you can use to implement SCPs, and how to iterate and improve SCPs as your workload and business needs change.

In this post, I will discuss how you can think of creating SCPs using constructs from AWS Well-Architected. I will use Organizational Units (OUs) names throughout this blog following the best practices of setting up Organizational Units (OUs) on AWS Organizations.

Creating SCPs based on AWS Well-Architected constructs

Let’s go through some of the key constructs of AWS Well-Architected pillars and see how you can think of creating SCPs. This is by no means an exhaustive list of SCPs covering all of the constructs of AWS Well-Architected.

What operational excellence pillar related SCPs can I apply to my OUs?

The operational excellence pillar focuses on running and monitoring systems to deliver business value, and to continually improve operational processes. Key objectives of the Operational Excellence pillar are:

  • Improved observability, including monitoring, log management, and workload telemetry
  • Rapid identification and remediation of issues introduced during deployment activities
  • Understanding workload health and detect deviation from established patterns of workload usage on production

To adhere to operational excellence principles, protecting resources that monitor your accounts for anomalies or configuration drift is essential.

One such resource is CloudWatch anomaly detection. You may want to prevent member accounts from altering anomaly monitors, alarms, or dashboards, which are issued by administrators (example, where names start with Admin-) at the same time giving flexibility to your developers to create, update, or delete monitors, alarms, or dashboards that they own. You can assign this SCP to your organization’s root , or to your foundational OUs (OU: Infrastructure, OU: Security, and OU: Workloads).

SCP: Deny Changes to CloudWatch monitors

Where to attach: At organization root, or infrastructure, security, and workloads OU

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyDisableCloudWatchMon", "Effect": "Deny", "Action": [ "cloudwatch:DeleteAlarms", "cloudwatch:DeleteAnomalyDetector", "cloudwatch:DeleteDashboards", "cloudwatch:PutAnomalyDetector", "cloudwatch:PutDashboard", "cloudwatch:PutMetricAlarm", "cloudwatch:SetAlarmState" ], "Resource": [ "arn:aws:cloudwatch:::alarm:Admin-*", "arn:aws:cloudwatch:::dashboard/Admin-*" ] } ]

In addition, AWS recommends that you create a guardrail to disallow changes to CloudWatch Logs log groups and prevent modifying retention policy. You can do that by attaching the following SCP in your root OU. Extending this SCP to AWS Control Tower created log groups is one of the mandatory guardrails available through AWS Control Tower.

SCP: Deny Changes to CloudWatch Logs

Where to attach: At organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyCWLogGroupRetentionPolicyUpdate", "Effect": "Deny", "Action": [ "logs:PutRetentionPolicy", "logs:DeleteLogGroup" ], "Resource": [ "*" ] } ]

AWS Config is a service that assesses, audits, and evaluates configurations of your AWS resources. AWS Config is used by customers as a compliance-as-code framework, and as a detective rules engine. You can attach the following SCP at the root OU to disallow AWS Config changes by member accounts across AWS Config Rules, Conformance Packs, and Multi-Account Multi-Region data aggregation.

SCP: Deny Changes to Config

Where to attach: At organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyChangesToConfig", "Effect": "Deny", "Action": [ "config:DeleteConfigRule", "config:DeleteConfigSnapshot", "config:DeleteConfigurationRecorder", "config:DeleteDeliveryChannel", "config:DeleteEvaluationResults", "config:DeleteOrganizationConfigRule", "config:DeleteResourceConfig", "config:DeleteRetentionConfiguration", "config:DeleteConformancePack", "config:DeleteAggregationAuthorization", "config:DeleteConfigurationAggregator", "config:StopConfigurationRecorder", "config:PutRetentionConfiguration", "config:PutConfigurationAggregator", "config:PutConfigurationRecorder" ], "Resource": [ "*" ] } ]

What security pillar related SCPs can I apply to my OUs?

The security pillar focuses on principles that strengthen your cloud security posture by

  • implementing least privilege access
  • separation of duties
  • defense in depth
  • data protection in transit and at rest
  • incident response

AWS recommends that you define security governance as a multi-layered strategy to manage risk at each level (i.e., foundational features that you inherit from AWS, platform features that you build on AWS, and application/business features that run on your platform).

Each of these layers should define security constants or security invariants. Security invariants are statements that will always hold true for your business and applications. An example of a security invariant is: “only authenticated and authorized users will have access to our API endpoints” or “security canaries will be always running on our CI/CD pipelines”. Each such security invariant defines a control that must be put in place to make that invariant achievable. These controls should form the basis of your desired security SCPs.

Note that determining security invariants and subsequent controls are not a one-time activity. You must stay up-to-date with AWS and industry recommendations and threat intelligence to evolve your threat model and control objectives.

For example, you should easily prevent the accidental removal of accounts from your organization. You can attach the following SCP at your organization root:

SCP: Deny accounts from leaving the organization

Where to attach: At organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "SCPforOULeavingOrgProtection", "Effect": "Deny", "Action": [ "organizations:LeaveOrganization" ], "Resource": [ "*" ] } ]

Make sure that you retire accounts that are unused, such as those from former employees, and then move them to OU: Suspended to protect your business from unwanted changes. Attach an SCP that denies *:* to this OU.

SCP: Deny all actions

Where to attach: Suspended OU (for unused accounts)

{ "Version": "2012-10-17", "Statement": [ { "Sid": "NoAWSAccess", "Effect": "Deny", "Action": "*", "Resource": "*" } ]

For accounts with OU: Sandbox, which your employees may use to learn and do proof of concepts on AWS services, turn off permissions such that users stay within your security guardrails. You can scope these SCPs to apply to all IAM users and roles except for administrator roles and to not apply to roles that you as an administrator create.

SCP: Deny access to IAM with role exception

Where to apply: Sandbox OU

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyAccessWithException", "Effect": "Deny", "Action": [ "iam:AttachRolePolicy", "iam:DeleteRole", "iam:DeleteRolePermissionsBoundary", "iam:DeleteRolePolicy", "iam:DetachRolePolicy", "iam:PutRolePermissionsBoundary", "iam:PutRolePolicy", "iam:UpdateAssumeRolePolicy", "iam:UpdateRole", "iam:UpdateRoleDescription" ], "Resource": [ "arn:aws:iam::*:role/name-of-role-to-deny" ], "Condition": { "StringNotLike": { "aws:PrincipalARN": "arn:aws:iam::*:role/name-of-admin-role-to-allow" } } } ]

As this OU is used for experimentation and learning purposes, you may also want to restrict accounts within this OU to operations to only particular regions. The following example SCP denies operations outside of eu-central-1 [Europe (Frankfurt)] and eu-west-1 (Europe (Ireland)] regions. You can replace this with any regions of your choosing. This SCP uses the NotAction statement to exempt global services or services with endpoints in us-east-1 [US East (N. Virginia)] so that these global services can be used, but any other requests to services in us-east-1 are denied. When using this SCP, make sure that you verify the list of services and include other global services in the NotAction statement as needed.

SCP: Deny actions outside approved regions

Where to apply: Sandbox OU, or any accounts/OUs where you have regulations that require region restrictions for your resources.

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyAllOutsideEU", "Effect": "Deny", "NotAction": [ "a4b:*", "acm:*", "aws-marketplace-management:*", "aws-marketplace:*", "aws-portal:*", "budgets:*", "ce:*", "chime:*", "cloudfront:*", "config:*", "cur:*", "directconnect:*", "ec2:DescribeRegions", "ec2:DescribeTransitGateways", "ec2:DescribeVpnGateways", "fms:*", "globalaccelerator:*", "health:*", "iam:*", "importexport:*", "kms:*", "mobileanalytics:*", "networkmanager:*", "organizations:*", "pricing:*", "route53:*", "route53domains:*", "s3:GetAccountPublic*", "s3:ListAllMyBuckets", "s3:PutAccountPublic*", "shield:*", "sts:*", "support:*", "trustedadvisor:*", "waf-regional:*", "waf:*", "wafv2:*", "wellarchitected:*" ], "Resource": "*", "Condition": { "StringNotEquals": { "aws:RequestedRegion": [ "eu-central-1", "eu-west-1" ] }, "ArnNotLike": { "aws:PrincipalARN": [ "arn:aws:iam::*:role/Role1AllowedToBypassThisSCP", "arn:aws:iam::*:role/Role2AllowedToBypassThisSCP" ] } } } ]

In addition to Sandbox OU, you will want to safeguard your organization from common exploits, such as unauthorized users using privilege escalations to exploit vulnerabilities in your IAM permissions. You must pass an IAM role to the service to configure many AWS services. This is a commonly used pattern to allow a service perform an action on your behalf. However, you will want to make sure that only these PassRole or GetRole actions are allowed when the request tag key (PassRoleKey) conforms to a special descriptor (PassRoleSpecialDescriptor). Replace PassRoleKey and PassRoleSpecialDescriptor to the key and values of your choice.

SCP: Deny ability to pass IAM roles

Where to attach: the organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyPassRoleWithoutSpecialDescriptor", "Effect": "Deny", "Action": [ "iam:PassRole", "iam:GetRole" ], "Resource": [ "*" ], "Condition": { "ForAllValues:StringNotEqualsIfExists": { "aws:RequestTag/PassRoleKey": [ "PassRoleSpecialDescriptor" ] } } } ]

You can protect secrets that you use for your database or applications by using AWS Secrets Manager. Secrets Manager helps you protect database credentials, API keys, OAuth tokens, and other secrets throughout their lifecycle. You can deny member accounts access to delete administrator issued secrets. You can attach this to OUs where administrator issued resources will make use of the secrets.

SCP: Deny changes to Secrets Manager

Where to attach: Wherever secrets are used (e.g. Workloads OU)

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenySecretUpdates1", "Effect": "Deny", "Action": [ "secretsmanager:UntagResource", "secretsmanager:GetSecretValue", "secretsmanager:RestoreSecret", "secretsmanager:DeleteSecret", "secretsmanager:UpdateSecret" ], "Resource": "arn:aws:secretsmanager:*:123456789012:secret:secret-id" }, { "Sid": "DenySecretUpdates2", "Effect": "Deny", "Action": "secretsmanager:ListSecrets", "Resource": "*" } ]

Amazon GuardDuty is a threat detection service that continuously monitors for malicious activity and unauthorized behavior to protect your AWS accounts, workloads, and data stored in Amazon Simple Storage Service (S3). As an owner of an administrator or delegated administrator GuardDuty account, you can enable and manage GuardDuty for any account in the organization.

You can use the following SCP to prevent changes to GuardDuty configurations by member accounts. You can use detector ID with wildcard as in the following example SCP “admin-detector-*” to protect administrator issued GuardDuty resources.

SCP: Deny changes to GuardDuty

Where to attach: the organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyGuardDutySpecificActions1", "Effect": "Deny", "Action": [ "guardduty:UpdateDetector", "guardduty:DeleteDetector" ], "Resource": "arn:aws:guardduty:*:123456789012:detector/admin-detector-*" }, { "Sid": "DenyGuardDutySpecificActions2", "Effect": "Deny", "Action": [ "guardduty:DisassociateFromMasterAccount", "guardduty:StopMonitoringMembers" ], "Resource": "*" } ]

What Cost Management pillar related SCPs can I apply to my OUs?

The cost management pillar focuses on principles of cost optimization and cost awareness. You can implement a culture of cost optimization by treating the cloud as a differentiator and not as you would your on-premises resource fleet. Among the many advantages of AWS, the most important are the ability to pay only for what you use, match your supply (of resources) exactly with the demand (of your business), and its elasticity that helps you pre-plan or over-provision for peak capacity. Accordingly, when thinking about SCPs related to this pillar, you can build a cost control foundation by implementing cost aware policies.

Using AWS Budgets Actions, you can define the action that you want to take in your account when a budget exceeds its threshold (actual or forecasted amounts). This level of control will let you reduce unintentional overspending in your accounts. You can attach the following SCP to your root OU which prevents member accounts from updating Budget actions.

SCP: Deny changes to AWS Budget Actions

Where to apply: the organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyCostManagementChanges", "Effect": "Deny", "Action": [ "budgets:ModifyBudget", "budgets:DeleteBudgetAction" ], "Resource": [ "arn:aws:budgets::*:budget/Admin-*/action/Admin-action-*" ], "Condition": { "StringNotLike": { "aws:PrincipalAccount": [ "arn:aws:iam::123456789012:root", "arn:aws:iam::123456789012:user/*", "arn:aws:iam::123456789012:role/*" ] } } } ]

In addition to the SCP above, you can review “How to manage cost overruns in your AWS multi-account environment,” a blog series that uses an AWS Budget action to set a restrictive SCP on accounts that surpass a budget threshold. This is another use-case that can be applied to your Sandbox OU to ensure you maintain cost controls for your experimental accounts.

AWS Cost Anomaly Detection leverages advanced machine learning (ML) technologies to identify anomalous spend and root causes, so that you can quickly take action. Cost anomaly detection saves you time by vending automated root cause analysis, pin-pointing potential cost drivers, such as usage type (e.g., data transfer cost), specific AWS service, Region, and member account(s). You can attach the following SCP to your root, which prevents member accounts from updating cost anomaly monitors. Replace the account ID with your management account ID. The admin- prefix denotes only a set of IAM users or IAM roles from the management account will have access to make updates to cost anomaly monitors.

SCP: Limit changes to Cost Anomaly Detection, except when using a specific IAM user or Role

Where to apply: the organization root

{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Deny", "Action": [ "ce:UpdateAnomalyMonitor", "ce:UpdateAnomalySubscription", "ce:DeleteAnomalySubscription", "ce:DeleteAnomalyMonitor" ], "Resource": "*", "Condition": { "ForAnyValue:StringNotLikeIfExists": { "aws:PrincipalAccount": [ "arn:aws:iam::123456789012:root", "arn:aws:iam::123456789012:user/admin-*", "arn:aws:iam::123456789012:role/admin-*" ] } } } ]


As you have seen above, SCPs provide a centralized mechanism to codify best practices and let your builders innovate while staying within your security guidelines. We have reviewed common constructs from AWS Well-Architected and provided you with some examples that you can further expand for your needs. You should spend time in creating acceptable patterns of permissions based on your business needs, team skills, and security invariants. Iterate often and improve/expand on these patterns as your cloud adoption matures. This will help you build a secure cloud foundation.

To get started with building your own organization, refer to the AWS Organizations Getting Started Guide and create your first SCP.

About the author

Som Chatterjee

Som is a Technical Program Manager at AWS and is based in New Jersey, USA. He likes to create content that our customers can leverage in everyday use. He is passionate about databases, security, and distributed systems.