SCP Best Practices

 
 

What is an SCP?

Service Control Policies (SCPs) offer central access controls for all IAM entities in AWS accounts. You can use them to enforce the permissions you want everyone in your business to follow or to be compliant with specific laws which you need to follow (eg.: you can deny regions or services to be DSGVO compliant). If you want to use SCPs you need to create and apply those SCPs through AWS Organizations - SCPs can be assigned to AWS accounts or Organizational Units (OUs).

AWS SCP Best Practices
AWS SCP Best Practices - example OU Layout

Something you should know about SCPs:

❗️ The Master account of the Organization can't be restricted by using SCPs.
❌ SCPs cannot restrict principals outside of the Organization.
⚠️ SCPs are similar to IAM boundaries.


In the following section I will introduce some of my and AWS SCP - Best Practices which I am using. This SCPs will help you to secure your accounts and resources - plus it will help you to avoid unnecessary costs.

Avoid unnecessary costs

Deny creation of expensive services

When using an Organization, expensive services should be deployed centrally and shared with all accounts eg. private ACM. That way you can save some costs.

SCP
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyACM",
            "Effect": "Deny",
            "Action": [
                "acm-pca:CreateCertificateAuthority",
                "acm-pca:DeleteCertificateAuthority",
                "acm-pca:CreatePermission",
                "acm-pca:DeletePermission",
                "acm-pca:DescribeCertificateAuthorityAuditReport",
                "acm-pca:RestoreCertificateAuthority",
                "acm-pca:TagCertificateAuthority",
                "acm-pca:UntagCertificateAuthority"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:PrincipalArn": "arn:aws:iam::*:role/AWS-CentralCostTeam"
                }
            }
        }
    ]
}

Deny purchasing of reserved instances

When using an Organization and your company need to manage reserved instances centrally you should limit the permissions to one team, which ensures that the reserved instances are fully used.

SCP
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyAccessToRI",
            "Effect": "Deny",
            "Action": [
                "ec2:PurchaseReservedInstancesOffering",
                "ec2:AcceptReservedInstancesExchangeQuote",
                "ec2:CancelCapacityReservation",
                "ec2:CancelReservedInstancesListing",
                "ec2:CreateCapacityReservation",
                "ec2:CreateReservedInstancesListing"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:PrincipalArn": "arn:aws:iam::*:role/AWS-CentralCostTeam"
                }
            }
        }
    ]
}

Deny creation of savings plans

The same procedure applies for savings plans as for reserved instances in an Organization.

SCP
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyAccessToCreateSavingsPlans",
            "Effect": "Deny",
            "Action": [
                "savingsplans:CreateSavingsPlans"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:PrincipalArn": "arn:aws:iam::*:role/AWS-CentralCostTeam"
                }
            }
        }
    ]
}


Secure resources and accounts

Deny all SCP

If your account gets compromised it is recommended to have a deny all SCP to protect your data. This SCP is attached to a quarantine OU, which prohibits every action in the compromised account.

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


Region enforcement

You need to be sure that your company just uses one region?! The following policy will enforce that your member accounts are using the specified region.
⚠️ You need to define the global services in the NotAction otherwise the accounts are not able to use them.

SCP
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RestrictToOneRegion",
            "Effect": "Deny",
            "NotAction": [
                "a4b:*",
                "artifact:*",
                "aws-portal:*",
                "budgets:*",
                "ce:*",
                "chime:*",
                "cloudfront:*",
                "cur:*",
                "datapipeline:GetAccountLimits",
                "directconnect:",
                "globalaccelerator:*",
                "health:*",
                "iam:*",
                "importexport:*",
                "mobileanalytics:*",
                "organizations:*",
                "resource-groups:*",
                "route53:*",
                "route53domains:*",
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets",
                "shield:*",
                "support:*",
                "tag:*",
                "trustedadvisor:*",
                "waf:*",
                "wellarchitected:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestedRegion": [
                        "eu-central-1"
                    ]
                }
            }
        }
    ]
}

⚠️ If you want to use Lambda@Edge you need to add also the service lambda:* to NotAction.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RestrictToOneRegion",
            "Effect": "Deny",
            "NotAction": [
                "lambda:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:RequestedRegion": [
                        "eu-central-1"
                    ]
                }
            }
        }
    ]
}


Secure Security-Baseline: Deny ability to disable GuardDuty

GuardDuty is a threat detection service that continuously monitors for malicious activity and unauthorized behavior in you accounts. In an Organization you should use a master account and connect member accounts to it. The following policy ensures it can’t be turned off, the member can't be disassociated from the master or that a user can't create sample findings.

SCP
  {
      "Effect": "Deny",
      "Action": [
        "guardduty:DeleteDetector",
        "guardduty:CreateSampleFindings",
        "guardduty:DisassociateFromMasterAccount"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotLike": {
          "aws:PrincipalArn": "arn:aws:iam::*:role/StackSet-GuardDuty-Member-LambdaExecutionRole*"
        }
      }
    }


Secure Security-Baseline: Deny ability to disable Config

Config is a service to audit and evaluate the configurations in your accounts. The following SCP prevents users or roles to disable or alter Config, except the specified role which is needed for a Lambda to enable and configure Config in all regions.

SCP
{
      "Effect": "Deny",
      "Action": [
        "config:DeleteConfigurationRecorder",
        "config:DeleteDeliveryChannel",
        "config:StopConfigurationRecorder",
        "config:PutDeliveryChannel",
        "config:StartConfigurationRecorder"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotLike": {
          "aws:PrincipalArn": "arn:aws:iam::*:role/StackSet-Enable-Config-*"
        }
      }
    }


Secure Security-Baseline: Deny leaving the Organization

Secure your Organization that no accounts can leave your Organization, where they would no longer be restricted by your SCPs.

SCP
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "organizations:LeaveOrganization",
        "Resource": "*"
    }
}


Deny root access

AWS recommends a SCP for denying use of the root user. The following policy enforces that the root user can't be used.

SCP
{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "DenyRootUser",
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
      "StringLike": { "aws:PrincipalArn": "arn:aws:iam::*:root" }
    }
  }
}


How to test SCPs or how to handle SCPs without breaking things?

Lets start with the bad news, unfortunately there is no audit mode for SCPs, but you can use the API - GetOrganizationsAccessReport from the IAM Access Advisor to identify unused services. This API will help you to see whether services are used in an account or OU. I always use a separate OU to test new SCPs by moving a test account to see, if my SCP works as desired.



      

AWS Landing Zone versus AWS Control Tower

What is the difference between AWS Landing Zones and AWS Control Tower? Customized Solution or Managed Service?!

 

Apr 20th 2020

 

David Krohn

SCP performance with ssm-agent

A performance comparison of scp with ssm-agent and without

 

Apr 3rd 2020

 

Sascha Lange

Using AWS KMS with golang

How-to encrypt and decrypt data with AWS KMS and the aws-sdk-go.

 

Mar 25th 2020

 

Sascha Lange