AWS Service Control Policies

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.

AWS Consulting

Introduction- AWS Service Control Policies

Service control policies (SCPs) are a type of organization policy that is used to manage permissions in an organization. Furthermore, 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.

Additionally, 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. Moreover, 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.

Moreover, in this article we will talk about a few policies like:

Production Specific Policies which you could apply for Production Environment.

In addition, 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

Furthermore, read the code below that we implemented for production specific policy:

Block service usage in all regions except Sydney. Moreover, 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

  • Furthermore, this policy requires Amazon Elastic Cloud Compute (EC2) instances to use a specific type.
  • Then allow only approved services.
  • GP inherited rules.
  • Block service usage in all regions except Sydney.
  • Then deny the 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: Furthermore, 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. Moreover, This means that if your users are in the console, there is no way to ask them to add tags upon RDS creation.

Additionally, 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

In conclusion, it is important to use the right policy to create workload as expected. If you do not follow the policy, then you will not get the permission. Additionally, setting up AWS control policies is beneficial as it ensures your account stays within your organization’s access control guidelines.

Proud Blogs that
make us stand
out

SAP Fieldglass Resume Ranking setup Recent Home

S/4 Hana

SAP Fieldglass Resume Ranking setup

Ensure seamless SAP Integration | Secure Access | Auth0 with third-party APIs. Secure authentication &…

Choosing the Right O365 Subscription: Monthly, Annual & Hybrid Commitments Recent Home

sub -O365

Choosing the Right O365 Subscription: Monthly, Annual & Hybrid Commitments

This article explores the various Microsoft 365 subscription models—monthly, annual, and hybrid—and helps you choose…

Peritos Wins Globalisation Excellence Award | MSME Star Stories 2024 Recent Home

Awards

Peritos Wins Globalisation Excellence Award | MSME Star Stories 2024

Peritos Solutions is proud to be a winner in the “Globalisation Excellence” category at MSME…

Peritos Wins at NABH Quality Connect Fiesta 2024 Recent Home

Awards

Peritos Wins at NABH Quality Connect Fiesta 2024

Peritos proudly receives the NABH Quality Connect Healthcare Quality Pitch Award at the 2024 Competitions…

Peritos: New Zealand ICT Award Finalist for Technical Award 2025 Recent Home

Awards

Peritos: New Zealand ICT Award Finalist for Technical Award 2025

Peritos Solutions has been named a finalist for the 2025 New Zealand ICT Technical Award,…

Thinking about a project? Get in touch with us.

Connect with Us Today through the Details Below or Fill
Out the Form for a Prompt Response

Book Free Consultation

Guaranteed response within 8 business hours.





    Trusted by Startups and Fortune 500 companies

    07+ years of experience

    We can handle projects of all complexities.

    100+ satisfied customers

    Startups to Fortune 500, we have worked with all.

    20+ in-house team

    Top 1% industry talent to ensure your digital success.