AWS Service Control Policies

Introduction- AWS Service Control Policies 

Service control policies (SCPs) are a type of organization policy that is used to manage permissions in an organization. AWS Service Control Policies offer central control over the maximum available permissions for all accounts in your organization. SCPs ensures that your accounts stay within the organization’s access control guidelines. 

Please note: There is no “audit” mode for SCPs or any other way to test if a SCP will break things.

SCPs cannot restrict the Master Account of the Organization. This is the primary reason behind not using the Organization Master Account for anything except Organization Activities. This means that you should not put S3 buckets, EC2s, or any other resources in your Organization Master, because you cannot use SCPs to create guardrails around that.

In this article we will talk about a few policies like:

Production Specific Policies which you could apply for Production Environment.

The test environment can have a set of different policies which can be used. For example, Sandbox Policies like:

  1. Restrict user to create 10x size EC2 instance.
  2. Allow only approved services rds
  3. lambda ec2 iam
  4. Restrict user for confidential services

Production specific AWS Control policies

Read the code below that we implemented for production specific policy:

Block service usage in all regions except Sydney. Block service access for the root user and Deny Account’s ability to leave the Organization.

{
  “Version”: “2012-10-17”,
  “Statement”: [
    {
      “Sid”: “1DenyAllOutsideSydney”,
      “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”: “ap-southeast-2”
        }
      }
    },
    {
      “Sid”: “2RestrictEC2ForRoot”,
      “Effect”: “Deny”,
      “Action”: [
        “ec2:*”,
        “s3:*”,
        “vpc:*”,
        “iam:*”
      ],
      “Resource”: [
        “*”
      ],
      “Condition”: {
        “StringLike”: {
          “aws:PrincipalArn”: [
            “arn:aws:iam::*:root”
          ]
        }
      }
    },
    {
      “Sid”: “3LeaveOrganization”,
      “Effect”: “Deny”,
      “Action”: [
        “organizations:LeaveOrganization”
      ],
      “Resource”: “*”
    }
  ]
}

Prevent resource creation without specifying mandatory tags

{
  “Version”: “2012-10-17”,
  “Statement”: [
    {
      “Sid”: “DenyCreateWithNoenvironmentTag”,
      “Effect”: “Deny”,
      “Action”: [
        “secretsmanager:CreateSecret”,
        “eks:CreateCluster”,
        “ecs:CreateCluster””true”
      ],
      “Resource”: “*”,
      “Condition”: {
        “Null”: {
          “aws:RequestTag/environment”:
        }
      }
    },
    {
      “Sid”: “DenyRunInstanceWithNoenvironmentTag”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”,
        “arn:aws:ec2:*:*:volume/*””true”
      ],
      “Condition”: {
        “Null”: {
          “aws:RequestTag/environment”:
        }
      }
    },
    {
      “Sid”: “DenyCreateWithNoCostCenterTag”,
      “Effect”: “Deny”,
      “Action”: [
        “secretsmanager:CreateSecret”,
        “eks:CreateCluster”,
        “ecs:CreateCluster”
      ],
      “Resource”: “*”,
      “Condition”: {
        “Null”: {
          “aws:RequestTag/costcenter”: “true”
        }
      }
    },
    {
      “Sid”: “DenyRunInstanceWithNoCostCenterTag”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”,
        “arn:aws:ec2:*:*:volume/*””true”
      ],
      “Condition”: {
        “Null”: {
          “aws:RequestTag/costcenter”:
        }
      }
    },
    {
      “Sid”: “DenyCreateWithNoapplicationTag”,
      “Effect”: “Deny”,
      “Action”: [
        “secretsmanager:CreateSecret”,
        “eks:CreateCluster”,
        “ecs:CreateCluster””true”
      ],
      “Resource”: “*”,
      “Condition”: {
        “Null”: {
          “aws:RequestTag/application”:
        }
      }
    },
    {
      “Sid”: “DenyRunInstanceWithNoapplicationTag”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”,
        “arn:aws:ec2:*:*:volume/*””true”
      ],
      “Condition”: {
        “Null”: {
          “aws:RequestTag/application”:
        }
      }
    },
    {
      “Sid”: “DenyCreateWithNoNameTag”,
      “Effect”: “Deny”,
      “Action”: [
        “secretsmanager:CreateSecret”,
        “eks:CreateCluster”,
        “ecs:CreateCluster”
      ],
      “Resource”: “*”,
      “Condition”: {
        “Null”: {
          “aws:RequestTag/Name”: “true”
        }
      }
    },
    {
      “Sid”: “DenyRunInstanceWithNoNameTag”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”,
        “arn:aws:ec2:*:*:volume/*”
      ],
      “Condition”: {
        “Null”: {
          “aws:RequestTag/Name”: “true”
        }
      }
    },
    {
      “Sid”: “DenyCreateWithNoplatformTag”,
      “Effect”: “Deny”,
      “Action”: [
        “secretsmanager:CreateSecret”,
        “eks:CreateCluster”,
        “ecs:CreateCluster””true”
      ],
      “Resource”: “*”,
      “Condition”: {
        “Null”: {
          “aws:RequestTag/platform”:
        }
      }
    },
    {
      “Sid”: “DenyRunInstanceWithNoplatformTag”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”,
        “arn:aws:ec2:*:*:volume/*”
      ],
      “Condition”: {
        “Null”: {
          “aws:RequestTag/platform”: “true”
        }
      }
    }
  ]
}

Resource Size AWS Control policies

It requires Amazon EC2 instances to use a specific type. 

{
  “Version”: “2012-10-17”,
  “Statement”: [
    {
      “Sid”: “Require10XorHigherInstanceType”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”
      ],
      “Condition”: {
        “StringNotEquals”: {
          “ec2:InstanceType”: [
            “c6gd.12xlarge”,
            “c6gd.16xlarge”,
            “c6gn.16xlarge”,
            “c6gn.12xlarge”,
            “c6gd.metal”,
            “c5d.metal”,
            “c5d.24xlarge”,
            “c5d.18xlarge”,
            “c5d.12xlarge”,
            “c5ad.24xlarge”,
            “c5ad.16xlarge”,
            “c5ad.12xlarge”,
            “c5n.metal”,
            “c5n.18xlarge”,
            “c5n.18xlarge”,
            “m6i.32xlarge”,
            “m6i.24xlarge”,
            “m6i.16xlarge”,
            “m6i.12xlarge”,
            “m5d.12xlarge”,
            “m5d.16xlarge”,
            “m5d.24xlarge”,
            “m5d.metal”,
            “m5ad.12xlarge”,
            “m5ad.16xlarge”,
            “m5ad.24xlarge”,
            “m5dn.12xlarge”,
            “m5dn.16xlarge”,
            “m5dn.24xlarge”,
            “m5dn.metal”,
            “m5zn.12xlarge”,
            “m5zn.metal”,
            “m4.10xlarge”,
            “m4.16xlarge”,
            “a1.4xlarge”,
            “a1.metal”
          ]
        }
      }
    }
  ]
}

To Require a tag on Resource creation and resource’s Name

 Application environment platform cost center

{
  “tags”: {
    “environment”: {
      “tag_value”: {
        “@@assign”: [
          “prod”,
          “uat”,
          “test”,
          “dev”
        ]
      },
      “enforced_for”: {
        “@@assign”: [
          “cloudfront:*”,
          “ec2:capacity-reservation”,
          “ec2:client-vpn-endpoint”,
          “ec2:customer-gateway”,
          “ec2:dhcp-options”,
          “ec2:elastic-ip”,
          “ec2:fleet”,
          “ec2:fpga-image”,
          “ec2:host-reservation”,
          “ec2:image”,
          “ec2:instance”,
          “ec2:internet-gateway”,
          “ec2:launch-template”,
          “ec2:natgateway”,
          “ec2:network-acl”,
          “ec2:network-interface”,
          “ec2:reserved-instances”,
          “ec2:route-table”,
          “ec2:security-group”,
          “ec2:snapshot”,
          “ec2:spot-instance-request”,
          “ec2:subnet”,
          “ec2:traffic-mirror-filter”,
          “ec2:traffic-mirror-session”,
          “ec2:traffic-mirror-target”,
          “ec2:volume”,
          “ec2:vpc”,
          “ec2:vpc-endpoint”,
          “ec2:vpc-endpoint-service”,
          “ec2:vpc-peering-connection”,
          “ec2:vpn-connection”,
          “ec2:vpn-gateway”,
          “lambda:*”,
          “rds:cluster”,
          “rds:cluster-endpoint”,
          “rds:cluster-pg”,
          “rds:cluster-snapshot”,
          “rds:db”,
          “rds:db-proxy”,
          “rds:db-proxy-endpoint”,
          “rds:es”,
          “rds:og”,
          “rds:pg”,
          “rds:ri”,
          “rds:secgrp”,
          “rds:snapshot”,
          “rds:subgrp”,
          “rds:target-group”,
          “s3:bucket”,
          “sns:topic”,
          “sqs:queue”
        ]
      }
    },
    “application”: {
      “tag_value”: {
        “@@assign”: []
      }
    },
    “costcenter”: {},
    “Name”: {},
    “platform”: {
      “tag_value”: {
        “@@assign”: [
          “windows”,
          “linux”,
          “aws”
        ]
      }
    }
  }
}

Sandbox Specific Policy

  • This policy requires Amazon Elastic Cloud Compute (EC2) instances to use a specific type.
  • Allow only approved services.
  • GP inherited rules.
  • Block service usage in all regions except Sydney.
  • Deny Account’s ability to leave the Organization.
{
  “Version”: “2012-10-17”,
  “Statement”: [
    {
      “Sid”: “1Require10XorHigherInstanceType”,
      “Effect”: “Deny”,
      “Action”: “ec2:RunInstances”,
      “Resource”: [
        “arn:aws:ec2:*:*:instance/*”
      ],
      “Condition”: {
        “StringEquals”: {
          “ec2:InstanceType”: [
            “c6gd.12xlarge”,
            “c6gd.16xlarge”,
            “c6gn.16xlarge”,
            “c6gn.12xlarge”,
            “c6gd.metal”,
            “c5d.metal”,
            “c5d.24xlarge”,
            “c5d.18xlarge”,
            “c5d.12xlarge”,
            “c5ad.24xlarge”,
            “c5ad.16xlarge”,
            “c5ad.12xlarge”,
            “c5n.metal”,
            “c5n.18xlarge”,
            “c5n.18xlarge”,
            “m6i.32xlarge”,
            “m6i.24xlarge”,
            “m6i.16xlarge”,
            “m6i.12xlarge”,
            “m5d.12xlarge”,
            “m5d.16xlarge”,
            “m5d.24xlarge”,
            “m5d.metal”,
            “m5ad.12xlarge”,
            “m5ad.16xlarge”,
            “m5ad.24xlarge”,
            “m5dn.12xlarge”,
            “m5dn.16xlarge”,
            “m5dn.24xlarge”,
            “m5dn.metal”,
            “m5zn.12xlarge”,
            “m5zn.metal”,
            “m4.10xlarge”,
            “m4.16xlarge”,
            “a1.4xlarge”,
            “a1.metal”,
            “c5.2xlarge”
          ]
        }
      }
    },
    {
      “Sid”: “SomeServices”,
      “Effect”: “Allow”,
      “Action”: [
        “rds:*”,
        “lambda:*”,
        “ec2:*”,
        “iam:*”
      ],
      “Resource”: “*”
    },
    {
      “Sid”: “NoConfidentialServices”,
      “Effect”: “Deny”,
      “Action”: [
        “a4b:*”,
        “acm:*”,
        “aws-marketplace-management:*”,
        “aws-marketplace:*”,
        “aws-portal:*”,
        “budgets:*”,
        “ce:*”,
        “chime:*”,
        “cloudfront:*”,
        “config:*”,
        “cur:*”,
        “directconnect:*”,
        “fms:*”,
        “globalaccelerator:*”,
        “health:*”,
        “importexport:*”,
        “kms:*”,
        “mobileanalytics:*”,
        “networkmanager:*”,
        “organizations:*”,
        “pricing:*”,
        “route53:*”,
        “route53domains:*”,
        “s3:GetAccountPublic*”,
        “s3:ListAllMyBuckets”,
        “s3:PutAccountPublic*”,
        “s3:*”,
        “shield:*”,
        “sts:*”,
        “support:*”,
        “trustedadvisor:*”,
        “waf-regional:*”,
        “waf:*”,
        “wafv2:*”,
        “wellarchitected:*”
      ],
      “Resource”: “*”
    }
  ]
}

Limitations

Limitations: We could not get a few of the services to work with the service control policies. However, policies like EC2, EKS, ECS and Secrets Manager worked fine. Although, Lambda and S3 buckets do not work with the tag restrictions because they do not support tag based authorization in IAM policies. Further, we could not get RDS, Athena, or Amplify to work because although, they may support tag-based restrictions in IAM policies, the consoles of those services do not let you add tags upon resource creation. 

For example, you can tag a RDS instance during creation in the CLI, but the console does not let you do it during creation. This means that if your users are in the console, there is no way to ask them to add tags upon RDS creation.

To know more, read this link AWS services that work with IAM – Compute services – https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work- with-iam.html#compute_svcs

Unit Test Screenshots

Below are the screenshots of the resources showing error when not followed with the policy.

Graphical user interface, application Description automatically generated with medium confidence When the policies are followed, it creates the workload as expected having the mandatory tags as enforced by the policy.

Conclusion- AWS Service Control Policies

It is important to use the right policy to create workload as expected. If you do not follow the policy, you will not get the permission. Setting up AWS Control Policies is beneficial as it ensures your account stays within your organization’s access control guidelines.  

Get In Touch If You Have A Business Query

Related Posts

AWS Consulting
AWS Service Control Policies

Read more about one of the architecture designs we did for a client for connecting ON premise to AWS Site to Site VPN in Control Tower.

Read More →
AWS Consulting
AWS Site to Site VPN in Control Tower- AWS Network Architecture

Read more about one of the architecture designs we did for a client for connecting ON premise to AWS Site to Site VPN in Control Tower.

Read More →
AWS Close Account Control Tower
AWS Control Tower Close Account

Read how AWS Control Tower Close Account makes it easy to manage your organization, however, you need to follow a set of steps to do it.

Read More →
×

Table of Contents