IAM is core to AWS, it controls who/what can sign in, what services they can use, and even what specific functionality of a service they can use. It can also be complicated if you don’t understand it, with confusion and troubleshooting leading to possible broad wildcard access to everything in the account to just “make it work”. Here are some best practices and security tips for using IAM.
Do not use the root user
Do not use the root user even if you are the only person using the AWS account. If you wan’t more info on this see this post.
Use groups to give users access
Instead of attaching policies directly to users, you should be creating groups for specific tasks. Does a Junior Developer need permissions to run codebuild and see the build artifacts in s3? Create a build group and assign them to it. Users can belong to 10 groups, and groups can have 10 policies attached to them.
Avoid inline policies
Inline policies can be quick and easy to create, but they can slip by and be hard to centrally manage. Using custom managed policies provides you with multiple benefits:
- Reusability - Have multiple services or users that need access to the same thing? You can reuse the same policy if you don’t have it inline.
- Central Management - Need to update that policy used by multiple services? Change it in one place and it gets updated for all.
- Versioning - Need to roll back a change you made that broke access for a service or user? I hope you didn't use an inline policy.
- Permissions Management - You can create admin users that have the ability to attach and detach policies, but can't create them.
- Automatic Updates - AWS provides many default policies that can be assigned to groups and services that receive new updates when new features and permissions come out so you don’t need to manage them.
You can convert your inline policies without downtime by copying the JSON document out of it, creating a new policy, attaching it, and removing the inline one.
Grant only the permissions required to accomplish a specific task. Start with the bare minimum and increase access when needed. If you start with broad access and try to reign it in later you are going to have a bad time.
Many people default to the wildcard actions because it’s easy. “My applications needs read and write access to this S3 bucket” is a good example. Sure… It needs the ability to read and write objects to that bucket, should it be able to delete objects? What about deleting the object versions? What about making that data public to the entire internet? what about unencrypting that data? and what about deleting the entire bucket?
When you use a wildcard permission for a resource you give full access to make changes most services would never need. Not only that you are also possibly giving future permissions for functionality that doesn't exist yet.
Even if you are not using the wildcard on the action, avoid using it for resources as well. Just because you have an application right now that needs access to every instance right now, doesn’t mean it will need it in the future.
Limit who can access IAM
All of the IAM policies in the world don’t matter if the users and services you attach them to have the ability to change, create, or attach policies to themselves. You can even go as far as keeping the IAM policy creating to a specific set of users not used for day to day activity.
Use roles for 3rd party access
Instead of creating keys or users for external access to your AWS account, use roles. AWS provides functionality to trust other accounts with access to a specific role. To set this up see this article.
These roles should also be using a unique External Id, as it provides additional security for your account.
Use roles for services and applications
Instead of creating a user and API keys for your applications and services (or worse using a users keys), use IAM roles and attach them to the servers. This way you can apply the “Least Privilege” method to your applications as well. These roles can be attached to servers, containers, or AWS services giving them access to only the specific things they need to function.
If you use IAM roles for application access, it can help prevent the leaking of AWS CLI Keys in code, environment variables, and logs.
Try out policy conditions
For extra security you can force users to require MFA, require a specified date or time range, and requests that come from a particular IP. This can be useful on destructive actions like preventing the termination of server from the CLI, accessing data in S3 from an unknown IP, or giving an auditor temporary access.
Policy conditions can be combined with tags to limit access to specific production or staging resources.
Never ever use NotAction
For some reason the AWS IAM team gave everyone the ability to use negative actions, they are confusing and should be avoided. Someone could easily accidentally give admin access when trying to prevent access to a specific resource. The Deny action should be used instead.
Monitor policy usage and creation
Stay up to date with your current policies, monitor for changes and service access. At Reconfig, we have create a security automation tool to help keep your IAM access safe and secure.