Securing an AWS account without Service Control Policies
If you are a single individual who has an AWS account that is not part of an organisation and therefore does not have access to AWS Organisations Service Control Policies, you will still want to apply principle of least priviledge to your IAM user.
These guides describe how to apply permissions boundaries to your IAM user so that you can only use the services and regions that you define. In the future you will need to login using your account’s root user in order to modify the permissions boundary.
Permissions boundaries
- Permissions boundaries for IAM entities
- Using permissions boundaries to limit the scope of IAM users and roles and prevent privilege escalation
- Delegate permission management to developers by using IAM permissions boundaries
Related IAM reference to aid building limited policies:
- IAM actions, resources, and condition keys for AWS services
- Using identity-based policies (IAM policies) for AWS Billing
Restricting region access
- Deny access to AWS based on the requested Region
- Control access to AWS regions using IAM policies
- Restricting access to enabling and disabling optional AWS regions
Additional recommendations
You should also enable and configure the following security and auditing services and facilities within your AWS account:
- AWS CloudTrail
- AWS Config
- AWS Security Hub
- AWS GuardDuty
- AWS Trusted Advisor
- AWS Inspector
- AWS SSM Patch Manager
Example permissions boundary policy
This policy limits the services that an IAM user may access, as well as restricting access to eu-west-2 (London) regions for non-global services. See the links above for a detailed explanation.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadOnlyCostAndBillingAccess",
"Effect": "Allow",
"Action": [
"aws-portal:View*",
"ce:*",
"cur:*",
"pricing:*",
"purchase-orders:View*",
"savingsplans:List*",
"savingsplans:Describe*",
"budgets:Describe*",
"budgets:View*"
],
"Resource": "*"
},
{
"Sid": "DenyWriteAccessToCostAndBilling",
"Effect": "Deny",
"Action": [
"account:*",
"aws-portal:Modify*",
"savingsplans:Create*",
"savingsplans:Delete*",
"savingsplans:Tag*",
"savingsplans:Untag*"
],
"Resource": "*"
},
{
"Sid": "AllowLimitedDeveloperComputeAccess",
"Effect": "Allow",
"Action": [
"account:ListRegions",
"cloudformation:*",
"cloudwatch:*",
"compute-optimizer:*",
"ec2:*",
"ec2messages:*",
"elasticloadbalancing:*",
"health:*",
"kms:*",
"logs:*",
"rds:*",
"resource-groups:*",
"route53:*",
"route53domains:*",
"s3:*",
"secretsmanager:*",
"sns:*",
"ssm:*",
"ssmmessages:*",
"sts:*",
"tag:*"
],
"Resource": "*"
},
{
"Sid": "AllowSecurityAndAuditAccess",
"Effect": "Allow",
"Action": [
"access-analyzer:*",
"cloudtrail:*",
"config:*",
"guardduty:*",
"iam:*",
"inspector2:*",
"securityhub:*",
"support:*",
"trustedadvisor:*"
],
"Resource": "*"
},
{
"Sid": "DenyIAMUserOrGroupAlteration",
"Effect": "Deny",
"Action": [
"iam:AddUserToGroup",
"iam:AttachGroupPolicy",
"iam:AttachUserPolicy",
"iam:CreateAccountAlias",
"iam:CreateGroup",
"iam:CreateLoginProfile",
"iam:CreateServiceLinkedRole",
"iam:CreateUser",
"iam:DeleteGroup",
"iam:DeleteGroupPolicy",
"iam:DeleteServiceLinkedRole",
"iam:DeleteUser",
"iam:DeleteUserPermissionsBoundary",
"iam:DeleteUserPolicy",
"iam:DetachGroupPolicy",
"iam:DetachUserPolicy",
"iam:PutUserPermissionsBoundary",
"iam:PutUserPolicy",
"iam:RemoveUserFromGroup",
"iam:UpdateGroup",
"iam:UpdateUser"
],
"Resource": "*"
},
{
"Sid": "DenyPermBoundaryIAMPolicyAlteration",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:CreatePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": [
"arn:aws:iam::ACCOUNT-ID:policy/ScopePermissions"
]
},
{
"Sid": "DenyRemovalOfPermBoundaryFromAnyRole",
"Effect": "Deny",
"Action": [
"iam:DeleteRolePermissionsBoundary"
],
"Resource": [
"arn:aws:iam::ACCOUNT-ID:role/*"
],
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT-ID:policy/ScopePermissions"
}
}
},
{
"Sid": "DenyAccessIfRequiredPermBoundaryIsNotBeingApplied",
"Effect": "Deny",
"Action": [
"iam:PutRolePermissionsBoundary"
],
"Resource": [
"arn:aws:iam::ACCOUNT-ID:role/*"
],
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT-ID:policy/ScopePermissions"
}
}
},
{
"Sid": "DenyRoleCreationWithOutPermBoundary",
"Effect": "Deny",
"Action": [
"iam:CreateRole"
],
"Resource": [
"arn:aws:iam::ACCOUNT-ID:role/*"
],
"Condition": {
"StringNotEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT-ID:policy/ScopePermissions"
}
}
},
{
"Sid": "DenyAllOutsideRequestedRegions",
"Effect": "Deny",
"NotAction": [
"access-analyzer:*",
"account:*",
"aws-portal:*",
"budgets:*",
"ce:*",
"cloudfront:*",
"cur:*",
"compute-optimizer:*",
"ec2:CopyImage",
"ec2:DescribeImages",
"ec2:DeregisterImage",
"ec2:RegisterImage",
"ec2:ModifyImageAttribute",
"health:*",
"iam:*",
"pricing:*",
"purchase-orders:*",
"route53:*",
"route53domains:*",
"s3:GetStorageLens*",
"savingsplans:*",
"support:*",
"trustedadvisor:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"eu-west-2"
]
}
}
},
{
"Sid": "DenyEc2CopyImageUnlessOwnerMatches",
"Effect": "Deny",
"Action": [
"ec2:CopyImage",
"ec2:DeregisterImage",
"ec2:RegisterImage",
"ec2:ModifyImageAttribute"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"ec2:Owner": [
"ACCOUNT-ID"
]
}
}
}
]
}