

"Loaded And Locked" by JD Hancock is licensed under CC BY 2.0.
The most important concept in secure design is the Principle of Least Privilege: if an entity does not require access to a resource, it should not have permission to access it. Building with this principle in mind helps build secure environments that limit the impact of security incidents.
However, a common mistake when building AWS infrastructure is using overly permissive IAM policies. IAM entities within AWS often have more permissions than they should. As a result, if one of these IAM entities is compromised, it can lead to an attacker getting significantly more access to your internal environment than otherwise possible.
In our fifth installment on the AWS Top 10 Security Issues, we’ll discuss the #5 priority for securing your AWS accounts: eliminating overly permissive IAM policies. This series highlights the most common security issues we at Cloud Security Partners have seen in our customers’ AWS accounts, and how to best address them.
IAM Policies
IAM policies are how access control is implemented within AWS. Policies are defined with a certain set of permissions, then attached to an IAM entity (a user, group of users, or IAM role) or IAM resource. Then, when an entity requests a resource, the IAM policy is evaluated; the request is only accepted if the user has permission to access the resource.
Policies can be created at three levels: AWS managed policies, customer-managed policies, or inline policies.
- AWS managed policies are created by AWS. They are an easy way to scaffold your IAM story, but cannot be customized for your environment.
- Customer-managed and inline policies are the most granular and are defined by your environment administrator. This control may, however, allow the creation of permissions with varied security effectiveness.
Permissions can be defined granularly or broadly; for example, a granularly scoped IAM policy like this may grant only read access to a specific S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-specific-bucket", // Access to the bucket
"arn:aws:s3:::my-specific-bucket/*" // Access to objects in the bucket
]
}
]
}
While a wildcard policy as follows could grant full administrator access across every resource within an AWS environment:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
IAM policies also support conditions. Conditions can be used to add more granularity to policies. For example, "Condition": {"StringEquals": {"aws:ResourceTag/Environment": "Production"}} ensures that a policy only applies if a resource contains a “Production” resource tag.
The combination of explicit labels and wildcards allows the creation of IAM policies with very different granularities. Unfortunately, this can also lead to IAM policies with overly broad permissions, potentially violating the Principle of Least Privilege.
Deny by Default: Least Privilege and Wildcards
The Principle of Least Privilege states that an entity should only have the minimum necessary permissions to perform required tasks. Permissions should be locked down to specific actions on specific resources. To follow this, permissions should be created as tightly scoped as possible.
For example, a microservice that writes to an S3 bucket should only have s3:write permissions. This way, if the microservice is compromised, an attacker would not have access to create new Lambdas or write to DynamoDB. Furthermore, this microservice should only be able to access that specific S3 bucket.
Using wildcards potentially violates this security principle. A wildcard policy like arn:aws:s3:::bucket-namespace-* matches all buckets named bucket-namespace-foo. This will allow access to new buckets created after the policy, potentially giving the underlying IAM entity access to unintended resources.
If wildcards must be used, they should be used sparingly with conditional constraints. Conditional constraints can limit an IAM policy’s exposure, especially when used in combination with resource tags. This can help create Least Privilege policies, but they may be harder to audit at scale. As such, avoiding wildcards should be your priority.
Analyzing and Creating Policies at Scale
Analyzing and creating AWS policies for all your resources can be difficult, depending on the scale of your organization. However, AWS IAM Access Analyzer makes it easy to analyze existing policies and craft new policies for all your resources quickly.
AWS IAM Access Analyzer has two critical features that help eliminate overly permissive IAM policies: access analyzers and policy generators.
IAM Access Analyzer has three different kinds of access analyzers: internal, external, and unused.
- The internal access analyzer gives visibility into who has access to what resources in your organization. This is useful to determine if any internal users who should not have access currently have access to sensitive resources.
- The external access analyzer helps identify if any external users have access to resources within your organization. This is incredibly useful to determine if any of your resources are publicly accessible or accessible from external AWS accounts or publicly reachable Internet endpoints.
- The unused access analyzer helps identify policies that are not used. This allows you to remove obsolete policies, improving your security posture by better adhering to Least Privilege.
The Policy generator feature helps create new security policies for resources based on existing CloudTrail logs. While the generated policies may not account for all edge cases, they are a great starting point for creating new least privileged policies.
Using both will help you drive down overpermissioned policies at scale. Access Analyzer will give you a picture of your current IAM posture. Policy Generator helps you define new tightly scoped policies based on existing logs, better adhering to the Principle of Least Privilege.
Service Control Policies
Service Control Policies are an additional feature for driving down overpermissioned policies in your AWS environment.
Service Control Policies allow you to create guardrail policies, which define the maximum permissions an IAM entity in your environment can have. This is an incredibly useful feature to prevent overly privileged IAM policies from being created and to limit existing policies.
However, Service Control Policies have certain limitations. They do not apply to external users or resource-based policies directly. As such, for full coverage, Service Control Policies should be used in conjunction with the Access Analyzer and Policy Generator features.
Checklist for Eliminating Overpermissioned IAM Policies
- Eliminate policies that contain wildcards *
- Any policies that can be made more specific should be replaced with the names of resources or paths they should access
- Ensure conditional constraints are applied to all wildcard policies
- Using resource tags can also help eliminate wildcard policies
- Run AWS IAM Access Analyzer
- Audit internal IAM access for least privilege
- Analyze Cross Account Roles
- Remove unused IAM policies
- Create new policies using AWS IAM Policy Generator
- Create Service Control Policies to limit maximum permissions
- Set up a regular IAM policy review schedule to ensure stale policies are removed
Conclusion
Overpermissioned IAM policies are one of the highest risks of any AWS environment, as they violate the Principle of Least Privilege. Auditing and removing them quickly secures your internal environment, significantly reducing the impact of any security incident.
This post is the fifth in our series on the AWS Top 10 Security Risks: each installment will dive deeper into the most common risks we see across customer environments and how to fix them. Stay tuned for the next blog, and if you’d like expert help evaluating your cloud security, reach out to Cloud Security Partners for a comprehensive assessment of your AWS environment.
Stay in the loop.
Subscribe for the latest in AI, Security, Cloud, and more—straight to your inbox.