AWS IAM Policies – Customer Managed VS AWS Managed. Which is better?
An AWS policy is a JSON document that defines a user role, or service’s permissions. AWS provides a bunch of pre-configured policies, otherwise known as AWS-managed policies. Alternatively, you can create your own, which are referred to as customer-managed policies. But which one is the better option?
AWS VS You
It’s a common misconception that AWS always knows best. Not to say that everyone at AWS isn’t amazing (you rock), but you shouldn’t be using their managed policies in your account. They even say so in their documentation which can be found here. But why is this?
To get started granting permissions to your users and workloads, use the AWS managed policies that grant permissions for many common use cases. They are available in your AWS account. Keep in mind that AWS managed policies might not grant least-privilege permissions for your specific use cases because they are available for use by all AWS customers. As a result, we recommend that you reduce permissions further by defining customer managed policies that are specific to your use cases. For more information, see AWS managed policies. For more information about AWS managed policies that are designed for specific job functions, see AWS managed policies for job functions.
AWS IAM best pratices documentation
AWS Managed policies are over-permissive by default.
AWS-managed policies tend to be over-permissive by default. This is because AWS needs to cater for every customer that may consider using this policy. Any managed policy you utilise in your account will most likely come with specific permissions your users won’t need. Therefore, it’s much better to use your own customer-managed policy and apply the principle of least privilege. Let’s look at an example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:GetTopicAttributes",
"sns:List*"
],
"Resource": "*"
}
]
}
This is the AmazonSNSReadOnlyAccess managed policy, which allows all read actions on SNS. Although this policy seems relatively harmless, it’s still possible to limit it further. For example, if you have several SNS topics in an account that each sends messages to a different app. Does everyone need access to all the SNS topics within the account? Probably not. Therefore, you can proceed to copy AWS’s managed policy but either limit the resources section or apply conditions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:GetTopicAttributes",
"sns:List*"
],
"Resource": "arn:aws:sns:us-east-1:111222333444:test_topic"
}
]
}
Now, the list permissions have only been applied to one very specific topic rather than all of them in the account. However, there is further limiting we could apply here. Do users of the topics need the ability to list everything? We can also proceed to limit the actual conditions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:ListTopics",
"sns:ListSubscriptions"
],
"Resource": "arn:aws:sns:us-east-1:111222333444:test_topic"
}
]
}
We’ve further limited the permission set so that only the topics and subscriptions can be listed, following the principle of least privilege.
Conclusion?
Although the policy listed above may seem basic and SNS topics, in general, are quite a basic service. This approach should be taken with all policies regardless of service or use case. Here are a few key things to check:
- Has the principle of least privilege been applied to the actions? (only grant precisely what is needed).
- Has the resource section of a policy been limited as much as possible? (specific resources wherever possible)
- Could you add a condition to the policy? (for example, check that the source IP is the office VPN IP)
Further Reading:
Check out a badly configured IAM role that could lead to an attack on your AWS account here
AWS documentation can be found here
AWS IAM policy generator here