In the second blog of our AWS Security Foundations series, we concentrate on managing your identities and their access to your AWS Cloud environments. According to Gartner, by 2023 75% of cloud security failures will result from insufficient management of identities, access and associated privileges. AWS IAM (Identity and Access Management) is a fundamental tool for protecting your AWS based services. It a super rich service but it can be difficult to configure well. Here we concentrate on our top tips and principles for a successful IAM implementation.
What is AWS IAM?
IAM is AWS’s service that allows you to finely control access to services and resources. It allows you to define different levels of access from very narrow to very broad. IAM uses policies to control access using factors such as use of MFA, network location and time of day. These policies applies to both end users (whether through the console or an API) and resources. IAM can also be integrated with your existing identity provider, such as Azure AD. This allows you to centralise the provisioning and de-provisioning of user accounts.
AWS IAM adopts a security first approach. What that means is that it uses a deny by default as a principle. If there is no policy that explicitly allows access, you will be denied access. Similarly, even if there is an explicit allow, an explicit deny always takes precedence. If you are using a multi-account AWS solution in an AWS Organization, you can also use Service Control Policies (SCPs) to put a boundary around allowed actions. SCPs are out of the scope of this discussion but we will cover them in later post!
IAM uses a JSON based policy. The policy consists of actions, resources, and conditions. In this example, we are allowing an EC2 instance to manage its own tags.
So, what are some of the more important approaches that you should follow when setting up IAM?
Following the principle of least principle is crucial. Simply, it means only providing access to resources and actions that are required to perform that function. In the context of a user account, you might allow the user to assume a role (more of that in a minute) to perform one particular action. If they then need to perform a different action, you may well use a different role.
The same principle applies to roles that you assign to an EC2 instance or to a Lambda function. In this way, if an instance were to be compromised, access to AWS services would be limited to the associated role. We’ve seen instances provided with an admin level policy. Don’t do this!
AWS has a policy simulator that can help to define the required permissions. You can also use an isolated sandpit environment to build restricted polices by performing actions and capturing the services and events from CloudTrail logs.
If you have an existing identity store, such as Azure AD, use that to provide temporary access into AWS. With Azure AD, you effectively manage access through AD Security Groups. These groups are associated with IAM roles to provide the temporary access. This means that the AD administrator is able to provide and remove access entirely from within AD. No user accounts need to be managed in AWS IAM. If you use MFA in your identity provider (highly recommended!), that will be enforced before a user can access AWS. Also, in the event of someone leaving your organisation, they will be unable to access AWS as soon as their account in AD is disabled.
If you have a multi-account AWS environment, the simplest way to integrate your identity provider is through AWS Single Sign-On. This will allow you to set up the integration once and then assign access across all your accounts. With AWS SSO, you assign permission sets (roles) to AWS accounts. AD Security Group membership then determines the available access for the user. Temporary access to accounts is provided through an SSO landing page.
Set a strong password policy
It’s a simple one, but you should always set a strong password policy, one that matches your corporate policy. If you don’t have an existing policy, we recommend something like the following. Note that if you are using an external identify provider, then the policy of that provider will apply. You will always have at least the root user in AWS anyway so you should set a strong IAM password policy.
Look under Account settings in the IAM console to find (and modify) the password policy.
Use roles over users
Instead of being associated with one person (every user who accesses AWS should have an individual, not group, user account), a role is assumable by anyone who needs it. Roles can be assigned and assumed by an IAM user or by a federated user who signs in using an external identity provider. A role is a way to group access and it provides short-term credentials only!
Roles are also the preferred method of providing access from third parties into your AWS environment. When the third party doesn’t support roles, ask they why not and when they will! If they really can’t support roles, then they will need an IAM user and associated API keys.
When you set up a role, not only do you define the allowed and denied actions and conditions but you also specify who you trust to assume the role. That may be an external party, an AWS service or an IAM user. The service or user may be from the same or a different account. Either way, following the principle of least privilege, only provide external access to accounts, services and users you trust. As an additional layer of protection, you can enforce that the calling account provides an externalID as further proof of their identity. Make these IDs unique to each account that is calling in to assume the role.
Assign roles to instances and functions
Assign roles to EC2 instances and to Lambda functions. Even if the instance or function requires no access to AWS services, it’s best to assign it a role. If you don’t then you will need to store credentials locally on the instance (or within the code or environment for a function). Storing API key credentials locally is a security and availability risk. A compromised EC2 instance will expose the API credentials. If the API credentials are revoked or rotated (see below), then access will be denied. Role solves both of these problems. They can, of course, be scaled to hundreds or thousands of instances or functions.
A role can be assigned to an EC2 instance at launch. It can also be assigned (or the role changed) later in the lifecycle of the instance. For a Lambda function, if you don’t specify a role, it will be assigned a default role. This default role only allows access for the function to upload logs to CloudWatch.
Rotate credentials regularly
If you do need to use IAM users and API access keys, then make sure you rotate them regularly. You can use AWS Config to report on API keys that have not been rotated in a defined time period. More on Config later in this series!
You can see the access keys associated with a user in the IAM console. You can create new keys and disable or delete keys too.
Monitor and tune access
Finally, once you have setup your IAM regime, created users and roles and provided access to the roles, it’s important to monitor the use of your IAM assets. Monitoring is important to understand who is accessing your environment but to also tune your policies and remove unused access.
- Use AWS Config to report on the age of access keys;
- Use AWS CloudTrail to understand who is assuming roles and from where. This is particularly important for roles that are assumed by external third parties;
- Within the IAM Console, you can see when roles or users have last been accessed;
- Additionally, policies associated with a user, group or role can be examined for their usage. Under a user, role or a policy, the Access Advisor tab will show when a particular service associated with a policy was last accessed. Services that have never been used will also be flagged. You can use this information to tune your policies, removing unused access;
- Within the console you can download a Credential report which shows a summary of user account and associated credentials;
- Finally, IAM Access Analyzer identifies IAM resources that are shared with external parties. It doesn’t monitor usage of the IAM resource by third parties but it can help you identify potentially unintended access permissions.
Building a robust AWS IAM environment is fundamental to managing access to your AWS resources. It’s simple to get going but can be tricky to get right! Don’t forget to monitor the usage of your IAM entities!
If you would like to dive deeper into IAM, please get in contact with us at RedBear. Look out for our next instalment in our AWS Security Foundations series next week!