globaldatanetmenu

.SCP Best Practices

Jul 20th 2020-5 min read

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 - 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.

{
    "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.

{
    "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.

{
    "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.

{    
  "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.

{
    "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.

  {
      "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.

{
      "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.

{
    "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.

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

Encryption

Encrypt everything - like Werner Vogels says. The following SCPs will help you that users are not able to create unencrypted resources for the following services.

Amazon S3 Buckets

This SCP ensures that all Amazon S3 buckets use AES256 encryption in an AWS Account. You can adjust that also for KMS Key usage you just need to change s3:x-amz-server-side-encryption to aws:kms.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "*",
            "Effect": "Deny",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption": "AES256"
                }
            }
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "*",
            "Effect": "Deny",
            "Condition": {
                "Bool": {
                    "s3:x-amz-server-side-encryption": false
                }
            }
        }
    ]
}

Amazon RDS

This SCP prevent creation of unencrypted RDS database.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RDS",
            "Effect": "Deny",
            "Action": [
                "rds:CreateDBInstance"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                    "rds:DatabaseEngine": [
                        "mariadb",
                        "mysql",
                        "oracle-ee",
                        "oracle-se2",
                        "oracle-se1",
                        "oracle-se",
                        "postgres",
                        "sqlserver-ee",
                        "sqlserver-se",
                        "sqlserver-ex",
                        "sqlserver-web"
                    ]
                },
                "Bool": {
                    "rds:StorageEncrypted": "false"
                }
            }
        },
        {
            "Sid": "Aurora",
            "Effect": "Deny",
            "Action": [
                "rds:CreateDBCluster"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "Bool": {
                    "rds:StorageEncrypted": "false"
                }
            }
        }
    ]
}

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.

globaldatanetCloud Development, Optimization & Automation

.Navigation

.Social

  • follow globaldatanet on instagram
  • follow globaldatanet on facebook
  • follow globaldatanet on twitter
  • follow globaldatanet on linkendin
  • follow globaldatanet on twitch
  •  listen to our serverless world podcast
  • follow globaldatanet's tech rss feed
  • follow globaldatanet at github
© 2024 by globaldatanet. All Right Reserved
Your privacy is important to us!

We use cookies on our website. Some of them are essential,while others help us to improve our online offer.
You can find more information in our Privacy policy