DevSecOps Engineering for Developers: Automated Least Privilege IAM Policy Generation for AWS From User Activity
Why Least Privilege Security Engineering Is Frequently Skipped or Done Loosely
In a previous life, I was on a team that reviewed the IAM policies specified by developers when they created new Cloud applications or required additional permissions for application updates that used new cloud features on AWS. The review was for both Infrastructure as Code automation for deployment as well as for Application runtime operations.
This task generally falls to the developer of the code because only they know the code operation well enough to ensure all code-paths are accommodated in least privilege discovery and testing during security engineering.
While reviewing the developer-authored permissions was very intense - the process developers used to determine the permissions was more intensive. A common methodology is to lock down the application or automation runtime permissions and go from failure to failure to discover the minimum permissions that are needed. This is incredibly labor intensive and on very large application or automation code bases it can add weeks to the release cycle. There is a much better way to do this that is much more productive and nearly eliminates deep rabbit hole explorations on permission dependencies in complex code.
A Well Kept Secret
AWS IAM Access Analyzer (Least Privilege) Policy Generator is already one of the best-kept secrets for AWS. The most tedious way to discover the least privileges for an application or infrastructure as code is to lock down a profile and work your way through all the failures one by one. There are multiple problems with the approach:
The sheer number of hours.
Many situations where deep dependencies between permissions make it difficult to understand exactly what permission is needed. This can lead to many failure iterations to isolate a single permission.
This is tough enough on small stacks, but at the level of production scaling stacks I've worked with - it becomes impossible.
This task is generally pushed to Application Developers in the case of applications - but it is not only out of many of their daily proficiencies - it is a very specialized area of cloud computing - permissions.
A Better Approach
If one could log EVERY permissions request, a much better approach is to give an application admin permissions, run it to exercise its capabilities and then aggregate the log information. There are many 3rd party scripts and utilities to do this for various permission systems. However, in AWS, there is a specific feature known as "Policy Generation" within the IAM Access Analyzer service. It analyzes CloudTrail logs (which have records for every required permission) to determine the least amount of permissions required for a given application or automation to run. The catch is the documentation and all blogs I've seen before always talk about using it against an IAM Role. This makes the setup more challenging because, unless you've done it before, running your application or automation using a role may require new skills.
An Even Better Kept Secret
However, IAM Access Analyzer has an even better-kept secret hidden within. Someone can correct me if I'm wrong, but I cannot find AWS documentation, blogs or videos on the following nuance of this feature.
When you are viewing an IAM User, clicking the "Generate policy" button in that user profile allows IAM Access Analyzer Policy Generator to use a USER ID to analyze the logs. This is very useful because using AWS Keys to exercise the application or automation is familiar to many more code developers - this means that one does not need to be as much of an AWS security specialist to leverage this automated security engineering feature. Using keys is also sufficient for security engineering since you can delete the keys or the entire user after doing your engineering.
Generate Policy button at the bottom of the default Permissions tab in an IAM user.
Practices to Consider
Additional good practices for using IAM Access Analyzer include:
Making it Comprehensive
Since IAM Access Analyzer is reverse engineering from log data - the entire application or automation must be exercised in order to discover all permissions.
For automation it can be easy to forget that it may create alternative infrastructure based on input parameters.
Since access analyzer takes a time range, you can run the automation many times to surface all the required permissions.
It may be prudent to create a test plan to ensure nothing is missed.
For Infrastructure as Code, the Initial run must be captured because IaC reports "true" for things that are already configured as desired ("Desired State") and does not attempt to configure them - so there will be no CloudTrail log data for things that are skipped due to already being configured.
For Infrastructure as Code, the teardown must also be captured if clean removal of resources with the least privilege permissions is desired.
Making it Faster:
Create a new role or user for the purpose of least privilege discovery so that there will be no other activity on the user id or role. This helps ensure that unneeded permissions are not added to the least privilege permissions since there simply isn't any unrelated activity to track.
Consider creating a new Cloud Trail to also limit the amount of data that will need to be analyzed. This also allows you to analyze account level data even if your organization has Cloud Trail implemented and collecting to a bucket the local account does not have access to. Don't forget to disable or delete it when done to prevent duplicate data collection.
When running the Access Analyzer you can also bound it by region that it examines - so if the entire application or automation runs can be in a single region, the data analysis will go even faster.
Making it Cleaner:
If you created a dedicated Cloud Trail, when done, deconfigure it and delete the bucket that houses the data.
When done, delete either the KEYS or the entire User or Role that was used for least privilege discovery.
Variation for Working Examples and Templates
The tightest least privilege IAM permissions are coded to specific resources. However, if your automation needs to handle many regions or many naming schemes, then you may need to replace the generated policy's variables with '*', these include any references with curly braces such as ${region}
and ${account}
.
Documentation and References
The following do not cover the user id functionality as far as I can tell: