tl;dr
You can't secure what you can't see.
AWS has dozens of policy types scattered across dozens of services, regions, and accounts.
iam-collect is built to find them all.
Answer your questions, secure your accounts, and make your customers safer.
Table of Contents
- 📚 So Many Policies, So Little Time
- 👤 Who's Doing What Around Here? (Principal Policies)
- 🔓 Who Left the Door Open? (Resource Policies)
- 🧟♂️ Oh Look, Even More Policies
- 📦 Fine, Just Download Everything - iam-collect
- 🔍 Okay, Now What?
- 🚀 The End is the Beginning
📚 So Many Policies, So Little Time
One of the best things about AWS IAM is it allows you to do almost anything. One of the challenging things about AWS IAM is it allows you to do almost anything. This flexibility is made possible through several different policy types. If you are in charge of any kind of AWS security or governance, it's critical you understand all of these and their impact.
So what are all these policies and how do we get them?
👤 Who's Doing What Around Here? (Principal Policies)
A principal is any entity that can take actions on AWS resources. It can be a user, a service, a role, or even a GitHub Action. These are in your account as IAM Users and Roles.
On their own, principal policies can only grant access to resources in the same account as the principal.
Managed Policies
These are the managed policies that can be used for multiple users, roles, and groups in your account. Every account comes with AWS Managed Policies that AWS creates and manages. Policies that you create and manage are called Customer Managed Policies.
User and Role Policies
Users and roles in AWS can have managed policies applied to them. They can also have inline policies attached directly to a single IAM user or role.
Group Policies
IAM users can be placed into groups. Groups can have both managed and inline policies, and every policy attached to a group applies to all users in that group.
Permission Boundaries
A permission boundary is a special managed policy that can be applied to a user or role to limit their overall access. Permission boundaries don't grant access, they define the outer limits of what a principal can do, even if other policies would normally allow it.
Service Control Policies
Service Control Policies (SCPs) are an AWS Organizations policy type that applies to principals in your organization. They can be applied to individual AWS accounts or groups of accounts called Organizational Units. SCPs can't grant access, they can only limit access.1 They are useful to enforce broad security rules across all your principals and can be significantly customized.
🔓 Who Left the Door Open? (Resource Policies)
With principal policies, you start with the principal and manage what resources they have access to. Resource policies are reversed, they start from the resource and manage what principals have access.
Resource policies unlock new capabilities, such as sharing a resource with a principal in another account, or an AWS service. Not every resource type supports resource policies.
Most resource policies apply to a single resource, but like all things AWS, it depends.
Resource policies are required for:
- Key Management Service (KMS) keys
- IAM Roles - the policies are called "trust policies"
For other resources, resource policies are optional.
IAM Role Trust Policies
Every IAM role has a trust policy that defines who can assume it. This policy controls access for sts:AssumeRole
, sts:AssumeRoleWithWebIdentity
, and sts:AssumeRoleWithSAML
calls. A principal must be allowed in the trust policy to assume the role, no matter what other policies say.2
Key Management Service Key Policies
Every key in Key Management Service (KMS) must have a resource policy defining what principals or accounts have access to that specific key. If access isn't granted through the KMS key policy, it won't happen—not even for the root user. It's possible to completely lock yourself out of a KMS key this way so be careful.
VPC Endpoint Policies
This is a kind of resource policies related to Private Link. When you create a VPC endpoint inside your VPC, a policy is always required. This policy determines what identities can send traffic through the endpoint and what resources they can access. By default all traffic is allowed but this can be customized with a policy document.
S3 Bucket and Access Point Policies
S3 buckets can have their own policies granting fine-grained access to the bucket or even specific prefixes with the bucket.
As bucket policies grew more complex, AWS introduced access points to "simplify" access management. Access points have their own policies. This way consumers can access a bucket through a dedicated access point that has its own detailed access point policy. There are single region and multi-region access points.
S3 also has object lambda access points that can be configured to run a lambda every time an S3 access point is used. Those have their own policies as well.
Different "S3" bucket types have different support for bucket policies and access points:
| Bucket Type | Bucket Policies | Access Points |
|-------------|----------------|---------------|
| General Purpose Buckets | ✅ | ✅ |
| S3 Table Buckets | ✅ | ❌ |
| S3 Vector Buckets | ✅ | ❌ |
| S3 Express Directory Buckets | ✅ | ✅ |
| S3 Outpost Buckets | ✅ | ✅ |
S3 Buckets also have per bucket and per account settings for Block Public Access.
Organizations Resource Policy
Typically AWS Organizations APIs can only be used from the management account of an organization. AWS has created this unfortunately named policy that allows you to delegate organizations API access to principals in other accounts.
Organizations Delegated Administrators
Many actions that are only allowed in the organization management account by default can be delegated to delegated administrator accounts, it's critical to know which accounts these are and what services they can manage.
Simple Email Service (SES) Sending and Identity Authorization Policies
In SES you can create resource policies for specific email identities (domains or email addresses) that allow other AWS accounts to send email from those identities. This is useful for organizations with a centralized identity management account that handles email domains.
You can also create a sending authorization policy that applies to your entire account. This is useful if you want to allow another account to send email on your behalf without having to create a resource policy for each identity.
Other Resource Policies
Tons of other resources support resource policies such as:
- API Gateway REST APIs
- Backup Vaults
- DynamoDB Tables and Streams
- ECR Registries - the registry for the entire region and account.
- ECR Repositories - every individual repository
- EFS File Systems
- Glacier Vaults
- Lambda Functions and Layer Version - Every layer version can have its own policy 😳
- SNS Topics
- SQS Queues
- Secrets Manager Secrets
- SSM Incident Manager Contacts and Response Plans
- Serverless Application Repositories
- Rekognition Projects
- Migration Hub Refactor Spaces
- Lex Bots
- Elemental Media Stores
- CodeBuild Report Groups and Artifact Repositories
- Signer Profiles
- Kinesis Data Streams
- Event Bridge Schema Registries and Buses
- CloudWatch Delivery Destinations
- CloudTrail Dashboards, Channels, and Event Data Stores
- Redshift Serverless Namespaces
- Redshift Namespaces
- OpenSearch Domains
- Managed Streaming for Kafka Clusters
Resource-ish Policies
Some custom policies in AWS don't apply directly to a single resource or account but are somewhere in between.
- AWS Entity Resolution allows custom policies for sharing multiple kinds of resources.
- AWS IoT allows a centralized policy for managing access to different IoT Resources
- CloudWatch Account Policies are managed at the account level for delegating access to CloudWatch Log Groups.
- AWS Glue has a per-region policy that can be used to manage access to any Glue resource in that region.
AWS Resource Access Manager
As you can see, lots of AWS resources allow you to attach policies to resources. Resource Access Manager (RAM) enables sharing resources when the service doesn't directly support resource policies.
You can think of RAM as "resource policies as a service". It allows you to share resources outside their account even if the service doesn't support resource policies. It has to be enabled by your AWS organization first. It supports 70+ resource types notably subnets, security groups, and firewalls.
Resource Control Polices
Finally there are resource control policies (RCPs), an AWS Organizations feature that allows you define policies that apply to all resources in an account or organization unit.
Remember: SCPs apply to principals in your organization, while RCPs apply to the resources themselves. Together, they help close the loop on what's allowed—and by whom.
🧟♂️ Oh Look, Even More Policies
IAM Identity Center Permission Sets
IAM Identity Center is used as a single sign on solution for accessing multiple roles in multiple AWS accounts from a single place. It provides user management or you can connect your own identity provider, such as Okta or Entra ID.
Within Identity Center you can create permission sets that define a set of policies (AWS managed, customer managed, inline, or a permission boundary) that can then be assigned to multiple user/account pairs. To know what permissions a user in Identity Center has, you need to have all of the permissions sets that apply to that user.
📦 Fine, Just Download Everything - iam-collect
That’s a lot of policies. And a lot of places for risk to hide.
iam-collect downloads IAM policies, organization policies, resource policies, RAM shares, and SSO permission sets, across every account, in one place.
Here is the quickest way to get started:
# Install
npm install -g @cloud-copilot/iam-collect
# Make a configuration file
iam-collect init
# Download data for the current account
iam-collect download
# Look at your data
ls -R ./iam-data
Now you have a full snapshot of IAM reality instead of assumptions or best guesses based on staring at Terraform.
💬 Real-world feedback:
iam-collect (and the accompanying iam-lens) were simple to stand up quickly and let us get straight to the interesting part: analyzing our tangled web of IAM policies. David has been incredibly receptive to feedback and quick to add new features as we've needed them. We're excited to use these tools even more in the future.
Jeremy Talis, Security Lead @ Pinterest
By default, it uses the credentials in your environment and saves data to the iam-data
folder. It requires a minimum set of permissions to operate.
A single folder can hold data for an unlimited number of AWS accounts and organizations across multiple partitions.
Customizing Data and Auth
iam-collect is built to be ridiculously configurable. You can:
- Select which accounts, services, and regions data will be collected from
- Assume a role in each account to collect data
- Assume an initial role before assuming roles in other accounts
- Have separate auth for each account
Storage Options
iam-collect can store data in:
- A folder on your local disk
- An S3 bucket with any prefix
🔍 Okay, Now What?
The primary purpose of iam-collect is to power iam-lens. We'll talk more about that in a future post and there is a lot you can do with it in the mean time.
Whether you're:
- a security lead trying to reduce audit time,
- a platform engineer building IAM tooling,
- or a consultant trying to answer “who can do what”
iam-collect
gives you a clean, reliable starting point.
🛠 Inspect Your Resources
Using a bit of cli and utilities like jq
you can quickly get information. Want to find all customer managed policies in your SSO permission sets? Try this:
ls collect/aws/aws/accounts/*/sso/permissionset/*/customermanagedpolicies.json | xargs -n1 jq -r '.[].arn' | uniq | sort
🤖 Data and AI, like peanut butter and chocolate
There are an infinite number of questions you might want answered with your IAM data. So iam-collect has a set of detailed agent instructions to use with your downloaded data.
Simply download the agent instructions:
curl -O https://raw.githubusercontent.com/cloud-copilot/iam-collect/main/docs/AgentInstructions.md
Then use these instructions to answer questions:
- What trust polices allow a Principal "*" to assume the role?
- What RAM shares are sharing resources outside of my organization?
- What managed policies that are in use use a wildcard "*" action?
- What AWS managed policies are in use?
- Are there any users in my root account without permission boundaries?
- What principals have a policy with the action "iam:PassRole" with a "*" resource?
These questions are about what the policies contain—not necessarily their full effect, which is harder for models to reason about. That's where iam-lens comes in later.
✨ Build Your Own Magic
Every year, new tools emerge to help analyze IAM policies, SCPs, and other access controls. They all start with the same first step: downloading policies from from AWS.
“First download all the policies” is often an annoying large part of the work; especially if you want to do it across multiple accounts and organizations.
I hope that by having a tool that just downloads the policies - which people may already have done - you can start with the most valuable step: bringing your industry expertise to AWS policies.
🚀 The End is the Beginning
No more guessing, clicking through the console, or trying to remember if that wildcard was "just for testing."
Start with the truth. Then secure it.
See the documentation to get started.
Footnotes
-
The way SCPs can limit access may include not having an
Allow
statement. See the full SCP documentation for details. ↩ -
You can use
arn:aws:iam::ACCOUNT_ID:root
to allow any principal in an account to assume a role. The principal still needs access to thests:AssumeRole
action in their own policies. ↩
Top comments (0)