Rightsize Your IAM Policies With The Principle of Least Privilege
An IAM (Identity and Access Management) policy is the fundamental gatekeeper for all IAM principles: users, groups, and roles. IAM Policies define what the principal is entitled to do and forbidden from doing using explicit allows and denies.
Without management or planning, IAM policies may swell in size to fulfill business needs without resistance. In the case of a security incident, these large policies can greatly increase the blast radius. Rightsizing a policy means limiting access to the resources it needs without consideration for future use. The only thing that should be evaluated when crafting a policy is the current business needs. Trying to plan for future or potential use can lead to security weaknesses which will be discussed in this article.
Some recent attacks leveraged over-privileged principals and could have been prevented with tightly scoped IAM policies. Aside from potential malicious actions, good policies prevent inadvertent actions like resource deletion, data leakage, or the creation of an attack vector.
To fully understand rightsizing IAM policies, it is important to understand three foundational concepts:
- Scope and Least Privilege
- Controls
- Infrastructure as Code (IaC)
Scope and Least Privilege
The scope of a policy dictates what it is allowed to do, explicitly. In AWS, principals without an allow
directive in the policy are denied by default unless there is a separate resource policy which grants access. An example of a resource policy is a bucket policy
in S3. Scope also defines which specific resources it can access within the allowed action, such as s3:GetObject
on a specific bucket and object.
The Principle of Least Privilege (Least Privilege) combines these two mechanisms to allow the bare minimum permissions needed to accomplish a task. Least Privilege also includes separating production environments from non-production environments.
Controls
Controls, in the case of IAM, are technical mechanisms to restrict access so only authorized users can make changes. Placing tight controls on IAM access ensures the integrity of resources, auditing access, and less management overhead. Two examples of this setup are a centralized “bastion” IAM-only AWS account in an organization that also uses Service Control Policies (SCPs) to restrict actions, and IAM policies that restrict which users can modify IAM resources.
Infrastructure as Code
IaC will make the above points easy to implement and visualize in addition to many other benefits such as:
- quick remediation of manual changes
- auditing desired versus current states
- reusing primitives such as resource names, variables, etc.
Terraform is an industry standard tool to manage your IaC for multiple types of resources. It supports all the major clouds and also supports other providers such as Kubernetes, Helm, and even Domino’s. In other words, you can manage your entire platform, from the infrastructure to the applications, in Terraform.
Applying the Principle of Least Privilege to IAM Policies
Applying Least Privilege requires a careful evaluation of the business needs for each resource and principal. For example, a developer may need permission to access Bucket-A but will never need access to Bucket-B. Therefore, you can craft the policy to allow S3 access for Bucket-A which would implicitly deny access to all other buckets by default.
Least Privilege can prevent inadvertent threat vectors: a developer making a power user for testing in prod, opening a NACL/Security Group, and so on.
Quick Tips
- Don’t add IAM actions beyond the minimum required
- Leverage Access Advisor to see unused granted actions
- Check CloudTrail for unintended or over-privileged access
- Define actions granularly -
s3:GetObject
instead ofs3:Get*
- Restrict actions to specific resources instead of using “
Resource": "*"
- Use conditions when practical, such as requiring MFA to be present
For increased security, make sure that:
- Password complexity requirements meet or exceed NIST SP-800-63B
- Users can change their own passwords (although using federated access is easier to manage centrally)
- MFA is required for all IAM users
- Root user has MFA is enabled and is only used for emergency actions
- External ID is required for third-party IAM role access
Terraform Example
The code snippet below creates a tightly scoped IAM policy as an easily auditable, reusable resource. Terraform policy resources accept the JSON generated from the AWS Policy Wizard and allows referencing resource names or variables inside the “Resource” directive.
resource "aws_iam_policy" "example" {
name = "example-policy"
description = "An example policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::${var.s3_bucket_name}"
},
{
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::${var.s3_bucket_name}/*"
}
]
}
EOF
}
Applying the Principle of Least Privilege to IAM Principals
Separating IAM principles by their respective functions is essential to following Least Privilege. This concept is explained in more detail in our earlier article “5 Things You Should Be Doing in IAM Right Now”.
Creating IAM groups allows an admin to define logically separate job functions and attach multiple tightly scoped policies to them instead of crafting one policy for each job function.
Place users into IAM groups and assign those groups permissions instead of assigning the permissions to IAM users directly. This will decrease management overhead and can increase security by discouraging admins from continuously adding permissions to a user. 1
Quick Tips
- Use separate groups, roles, or users for each business function
- Likewise, don’t reuse groups, roles, or users
- Create multiple tightly scoped policies and attach them to groups instead of using one large policy
- Use Customer Managed Policies instead of Inline Policies (one off policies directly attached to a principal)
Terraform Example
This code snippet creates an IAM group and a reusable IAM policy that is attached to the group.
resource "aws_iam_group" "devs" {
name = "devs"
path = "/groups/"
}
resource "aws_iam_policy" "dev_policy" {
name = "dev-policy"
description = "A policy for devs"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::${var.s3_bucket_name}"
}
]
}
EOF
}
resource "aws_iam_group_policy_attachment" "dev-attach" {
group = "${aws_iam_group.devs.name}"
policy_arn = "${aws_iam_policy.dev_policy.arn}"
}
Measuring Success
Quantifying both the effort spent to apply Least Privilege and the overall change are important for executive buy-in and measuring success. Here are some ways to do this:
-
Measure the number of Trusted Advisor IAM alerts before and after the changes.
-
Use Access Advisor to measure the number of unused permissions before and after the changes.
-
Check Cloudtrail logs to audit for unnecessary access before and after the changes.
-
Depending on the environment, use vulnerability scanners that can enumerate IAM principals and compare the results before and after the changes.
Conclusion
Applying Least Privilege to your IAM resources is an essential component of good security posture. Using the tips in this article can help guide you through rightsizing IAM policies and protecting your Cloud resources from a malicious attack or a harmful, inadvertent action.
Connect with ScaleSec for AWS business
ScaleSec is an APN Consulting Partner guiding AWS customers through security and compliance challenges. ScaleSec’s compliance advisory and implementation services help teams leverage cloud-native services on AWS. We are hiring!
Connect with ScaleSec for AWS business.