Effective IAM for AWS

Understand what your IAM policies actually do

Understand what your IAM policies actually do

Prove it.
— Vito Paine, Engineer

Now you know how to create distinct security domains, govern capabilities with SCPs, and protect data with least privilege security policies.

But how can you tell your policies do what you think they do?

It's one thing for you to know how to configure IAM. It's another thing for your organization to actually do it as intended every day.

AWS deployments are complex systems with independent and interacting agents: you, your teams, AWS. Best intentions and efforts do not secure APIs & data. And it's easy to make mistakes, as described in 'Why AWS IAM is so hard to use'.

You need to know your policies actually work.

And you need to know where the problems are today.

In this chapter, you will learn how to assess access quickly so you can audit frequently.

You should operate several IAM access control processes that identify excess privileges continuously. Identify in each AWS account:

  • unused principals
  • access granted to external and internal principals by resource policies for IAM roles and data resources
  • access capabilities granted to principals to use AWS services and resources in your account

Identifying excess access capabilities within an account is arguably the most important and most difficult control to operationalize. So we will show you how to do that using several approaches.


Close the loop

We anticipated adjusting and monitoring access when we initially provisioned IAM principals and policies:

Secure data using process control with feedback

Figure 7.1 Secure data using process control with feedback

To close our control loop, we need sensors to gather data from the running system so that we can analyze the system's actual state.

The primary problems we face are scale and accuracy. We want to verify conditions like:

  • only authorized principals have access to your data
  • buckets, keys, and roles are not externally accessible
  • only the expected principals can administer IAM and the account

The control loop needs sensors to analyze the entire AWS account and report effective access. The sensors should report access in a form that is easy for the process controller to understand and act upon. The process controller is the people, processes, and automation controlling access.

Do not use people to implement the sensing portion of the control loop. If you ask people to be your access evaluation engine, you'll quickly exceed their capacity, and they'll be inaccurate to boot.

Instead, automate reporting who has access to what in AWS so people can consume that reporting. Many AWS accounts have hundreds of principals and resources, or more. Even reporting access in a way people can quickly understand is a challenge. These reports need to accurately summarize a lot of data to help engineers across the Gulf of Evaluation.

Automated access analysis methods

Let's examine several approaches for analyzing IAM access using native AWS services, static policy analyzers, and dynamic access analyzers. This section will describe each class of tool and its capabilities. We'll illustrate each tool's capabilities for two common scenarios, understanding:

  1. Who is an IAM administrator?
  2. Who can access data in an S3 bucket?

Native AWS

The AWS IAM service provides several helpful capabilities via the console and APIs:

  • Policy validator
  • Access Analyzer
  • IAM simulator

Policy Validator

The AWS IAM Access Analyzer Policy Validator tool is an AWS security policy linter. Policy Validator identifies when a policy is invalid, overly permissive, or deviates from best practice. Validator provides feedback on policies as you write them in the AWS console or via API (full explainer). The Validator supports more than 100 policy checks. The +10 Security Warnings identify likely problems arising from misuse of advanced security language features like NotPrincipal, NotResource, and iam:PassRole.

The Validator analyzes a single policy in isolation, so its power is limited. The Validator does not know the principals or resources the policy is attached to or what other policies are in effect. Consequently, the Validator and similar linters cannot say whether a principal has the ability to administer IAM or access specific data sources.

Access Analyzer

The AWS IAM Access Analyzer tool suite sounds exactly like what we want, at least at first. Access Analyzer provides two capabilities.

First, Access Analyzer tells you when principals outside of your account can access the account's resources via a resource policy. This is extremely useful. Access Analyzer helps you identify S3 buckets, KMS Keys, SQS queues, and more that are accessible publicly or from another account. Access Analyzer reports the resource that is accessible, the principals that can access it, and which API actions they can invoke, e.g. s3:GetObject.

Access Analyzer does not analyze principals' access within the account.

So we have a very helpful, but incomplete answer to our second question about who can access data in an S3 bucket.

Second, Access Analyzer's 'last used' feature tells you when a principal last used an AWS service. For some services like IAM, it also reports when a principal last used each service API action. This is helpful for determining if a principal is actually using permissions it was granted. But it does not tell you if a principal could administer IAM.

But there is another tool.

IAM simulator

The AWS IAM simulator lets you simulate what would happen if a principal executed an AWS API request. The simulator supports specifying request resources, relevant policies, and policy context keys. Then the simulator reports whether the API request would be allowed or denied, and why.

This gives you the low-level data you need to assess access capabilities.


  1. There are many possible combinations to test. Interactive use of the simulator is best for tasks like verifying that your S3 bucket policy does what you think it does during development. Fortunately, you can automate verification of certain properties via the IAM simulator APIs.
  2. The simulator reports access at a very fine-grained technical level. e.g. Principal A is allowed to call iam:CreatePolicy, iam:AttachPolicy, and ten other actions. Not "Principal A is allowed to administer IAM."

So you can use the simulator to check if a principal can administer IAM or access data in S3, at least at small scale.

Now let's move from specific native AWS tools to the general class of policy analysis tools.

Policy analyzers

Policy analyzers report whether a (proposed) policy: grants a certain capability, aligns to best practice, or violates some rule.

Strengths: Most policy analyzers are available as command-line tools for easy integration into development and delivery processes. They usually accept policies as both local files and policy ARNs. So they can run frequently and provide fast feedback to change authors and other process controllers.

Policy analyzers are generally good at identifying whether a specific policy grants IAM administration capabilities or makes a bucket public.

Weaknesses: Policy analyzers typically analyze a single policy at a time or the resources within a particular change plan. So they probably won't account for interactions between policies and may miss context that controllers care about.

Here's how policy analyzers perform on our audit questions:

Q1. Who is an IAM administrator?

Static policy analyzers usually report which policies grant IAM administration or full access capabilities. However, they probably cannot identify IAM administrators directly.

Q2. Who can access data in an S3 bucket?

Static policy analyzers usually cannot report which IAM principals have access to data in an S3 bucket. Answering this question requires analyzing all the account's principals and identity policies according to the AWS policy evaluation logic, not just a single resource policy.

Access analyzers

Access analyzers examine the policies, principals, and resources in an account then report principals' effective access. They operate with much more context and can answer many more questions than a policy analyzer. Access analyzers report whether a principal may:

  • change security policies
  • delete databases or a particular database
  • decrypt data with a particular key

Access analyzers may report access to AWS APIs or high level access capabilities to AWS services. Some analyzers report access to specific resources.

The primary challenges for access analyzers are to:

  1. Evaluate access accurately, accounting for at least Service Control, Identity, and Resource policies
  2. Scale analysis to large numbers of principals and resources
  3. Report access in a way that can be understood

Each access analyzer is built on an IAM access evaluation engine. Some access analyzers use the AWS IAM simulation APIs. Some analyzers implement their own IAM access evaluation engine. An analyzer built on the simulation APIs uses the actual AWS IAM evaluation engine and the account's service control policies, but is difficult to scale. A 3rd-party evaluation engine is easier to scale, but must implement IAM security policy semantics, which is difficult to do correctly.

Capable access analyzers answer both of our questions.

Access is usually organized into a table of allowed operations. Consider this hypothetical access report excerpt:

... snip ...

This example illustrates the third challenge: reporting access so it can be understood by the people and automation controlling access.

Let's return to our questions.

Q1. Who is an IAM administrator?

We can conclude that appA principal is not an IAM administrator because no access to iam is reported. We would need to see a full report for all principals to understand who is and is not an IAM administrator.

Q2. Who can access data in an S3 bucket?

appA can invoke a couple s3 APIs, GetObject and GetObjectVersion, which allows retrieving data. The table saysappA can use these APIs with resources: *, sensitive-app-data, and bucket-1. Suppose this notation means the principal can get objects:

  • from buckets generally (*), meaning the principal can invoke those S3 APIs generally against all bucket objects in the account unless denied by a specific bucket policy
  • from two specific buckets: sensitive-app-data and bucket-1 after accounting for their resource policies

This information may help the people managing appA or this AWS account evaluate access. We can see appA has access to sensitive-app-data, which we granted in 'Control access to any resource'. We can also guess that appA has access to all buckets in the account, unless denied by a specific bucket policy. bucket-1's bucket resource policy certainly does not deny access to appA.

Should appA have access to bucket-1 or unrestricted access to S3:GetObject operations? Probably not, but we don't know. There's very little context available to support a decision.

Context is crucial when evaluating access to resources, particularly:

  • Owner
  • Application
  • DataClassification or expected Confidentiality

(See this Cloud deployment tagging guide for a full treatment of this topic.)

This context helps us go from the initial question of "who has access to data in S3?" to "should a principal have access to data in S3?"

Evaluating each principal's access to each of the thousands of AWS API actions and resources overloads people quickly. First with sheer volume. Second, is it meaningful to distinguish between s3:GetObject and s3:GetObjectVersion? Those are both operations for reading data. Most analysts benefit from aggregating the read capabilities into a single row.

Aggregating actions by capability:

  1. simplifies analysis to a handful of categories
  2. offloads the effort of categorizing API actions to a consistent automated process
  3. complements declaring intended access with high-level capabilities

Consider this report designed to help analysts evaluate access quickly:

PrincipalServiceCapabilityResourceOwnerData Classification
appAKMSread-datakey-1234Team AInternal
appAS3read-datasensitive-app-data/*Team AConfidential
appAS3read-databucket-1/*Team BInternal
... snip ...

Analysts and automation can evaluate reports using plain, high-level language with more context. They can consume this information easily and focus on important questions.

For example, an engineer on appA's delivery team can easily confirm appA needs read capabilities to sensitive-app-data. They can also easily determine that appA has unneeded access to other buckets. An automated analysis program can easily identify principals with access to many S3 buckets. It can also determine which resources are classified as Confidential and are accessible by more than 10 principals.

Having showed this style of report to many security practitioners, I have observed:

  1. everyone understands this form right away and starts to dig into their data
  2. people rarely have questions about what API actions are grouped into a capability1

People go straight to analyzing their access and identifying excess permissions, particularly to:

  1. administer IAM
  2. read, write, and delete critical data sources and keys
  3. use IAM role resources

This is exactly what we want. Process controllers analyze the report quickly and decide what to do next.

Find IAM administrators quickly

Understanding IAM administrators is so important that further optimization is warranted.

IAM administration capabilities could be represented in the Principal-Service-Capability form:

... snip ...

The table clearly shows the admin and temp-incident-response-q4 principals can administer IAM resources. But it could be clearer. Analyzers can report who the IAM administrators are directly:

PrincipalIs IAM Admin?
... snip ...

This form is very easy to filter for IAM admins and diff for changes. Because the burden for consuming this information by the process controller is so low, this information is suitable for a frequently-executed access review loop: weekly, daily, continuously.


We started with the goal of creating an effective access management control loop. The most difficult part of implementing AWS access controls is implementing the sensor component because understanding the effects of policies is so difficult.

AWS security policy and access analyzers differ in the kinds of questions they try to answer. Policy analyzers focus on policies, access analyzers on effective access to APIs and resources. They also differ in power, accuracy, and speed.

The sensor component must provide actionable information to the process controller so it can accurately and efficiently decide if a change is needed. The definitions of efficiently and accurately will vary by organization. But if you want to execute a control loop once a month or more frequently, process controllers will need to make hundreds of access review decisions quickly. Select sensor components that meet your efficiency and accuracy requirements. Support process controllers with information that helps them decide if a change is needed in less than 30 seconds per decision.

In the next chapter, we'll describe how to secure AWS continuously and describe how to operationalize the process in your organization.

  1. the access capabilities are well-defined, and capability-action mapping reference provided
Edit this page on GitHub