Least Privilege - Semi-Automated
In almost every tutorial on AWS you will come across the term “Least Privilege”. Writing IAM policies properly requires lots of research and time - that’s the reason why many projects still rely on AWS Managed Policies or write exploitable policies. But there are tools to help you along.
If you ever tried writing a policy following the Least Privilege principle, you will know the pains of that. Which IAM action maps to the activity I want to allow/deny? Are there any other IAM actions needed to use it on the AWS Web Console? Does the resource even support narrowing down target resources?
Over the last years, AWS documentation has improved a lot and now details Actions, related ARN formats and supported conditions.
But even introducing the IAM Access Analyzer does not help in all circumstances, as it currently only supports a limited set of resources.
AWS Console Recorder and IAMLive
Luckily, one of the consulting catchphrases (“You can find something on GitHub”) holds true: Ian McKay, an APN Ambassador and Community Hero, published two different projects which help you find out needed IAM privileges for certain actions.
The first one is AWS Console Recoder, which can record your steps in a Web Browser and not only output some IAM policies for it but actually even Terraform/CloudFormation/…
But, personally, I find his iamlive even more interesting: This tool can record outgoing API requests from running programs and output an IAM policy for them.
IAMLive CSM Mode
In late 2018 the AWS CLI has been extended by a feature called “Client Side Monitoring” (short: CSM) which can help with debugging local CLI calls. In its heart, this outputs JSON documents for all API calls onto a specified port (default: 31000/UDP
).
# Sets `csm_enabled` property in your config - will remove it on exit
iamlive --set-ini --output-file policy.json --background
aws s3 ls
aws s3 ls my-private-bucket
killall iamlive # stop the program
Ian’s tool uses this to extract the called AWS service and API function and his code can create a simple IAM policy out of it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:ListBucket"
],
"Resource": "*"
}
]
}
As you can see, the resulting policy just contains the actually called actions. You can use this as a base to write your IAM policies, adding specific resources and conditions.
IAMLive Proxy Mode
But, with a bit of configuration you can use a more powerful mode of iamlive
- Proxy mode. This feature was added in March 2021 with the 0.18 release.
It does something which is popular as “Man in the Middle” attack. By generating a self-signed certificate and configuring the AWS CLI to trust this one, it can intercept the requests sent to AWS.
# Sets `ca_bundle` property in your config for SSL Man-in-the-Middle - will remove it on exit
iamlive --set-ini --output-file policy.json --background --mode proxy
export HTTP_PROXY=http://127.0.0.1:10080
export HTTPS_PROXY=http://127.0.0.1:10080
aws s3 ls
aws s3 my-private-bucket
killall iamlive
As all calls towards the AWS CLI could be read by iamlive, we now get something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::my-private-bucket"
}
]
}
You probably immediately noticed that we now can see resources and are one step closer to a usable policy.
Potential Uses
Of course, just deploying the generated policies will not cover all use cases and will not include any Conditions at all. But it offers a nice way to get largely appropriate policies which only need minor tweaking (given you covered all necessary code execution path).
While performing AWS Security Reviews for customers, I often see CI/CD pipelines which have administrative privileges on all accounts. Especially after the recent supply chain attacks, this should raise some internal alarms. What if your CI/CD code actually contains injection weaknesses? Or if you install software into your runners without version pinning or checksum validation which has been backdoored? In those cases all your infrastructure is at risk.
But it is not enough to just trace all API calls in your terraform apply
call. Trust me, that was one of the first things I tried. On the one hand, the addressed resources might vary between your acceptance and production accounts. But on the other hand, the generated policies will be huge. Currently, managed IAM policies can contain 6 kilobytes of data. This means you likely have to split up your policies into separate documents and might even run into the 20 policies hard limit.
So, “automatically least privilege” pipelines are still a bit of science fiction. But the presented tool will make your job much easier.
I already have some ideas on how to “compress” those verbose IAM policies down to a usable policy - it just needs a bit more work… To be continued!