AWS methods for granting & controlling access, plus native tools for detecting & repairing excessive permissions.
Achieving least privilege access permissions configured in any cloud environment, and AWS in particular, is quite a challenge. For one, configuring resources, identities and permissions in Amazon’s Identity and Access Management (IAM) service is complex. Secondly, the environments and requirements coming from an organization’s different business functions is highly dynamic. Both challenges make it near-impossible to set permissions to the needed minimum - and likely harder to keep them that way.
Although it might still not be a top priority for many security professionals, defining least privilege access is one of the most significant tasks to perform well. Why? Because least privilege access is a key action for ensuring a cloud environment is resilient to security threats that can compromise the mission-critical computing functions and sensitive data that it is hosting. While most components of a cloud infrastructure can (and, let’s be honest, likely will) be compromised, it is the imperative of security stakeholders to curb the potential blast radius of such a breach by limiting permissions to what a component really needs. In the many environments we see on a daily basis, an average of ~80% of permissions are excessive, and those actually needed are typically dramatically less.
In this post we will review the methods in AWS for granting and controlling access. We will also discuss the main native tools AWS offers for detecting and even repairing excessive permissions -- and explore what they lack in scale, automation, granularity and context setting. Finally, we will illustrate how to close these gaps using an automated analysis platform that can really take a cloud infrastructure’s security to the next level and put an organization ahead of the threat risk curve.
Granting and Controlling Permissions
Let’s start by briefly reviewing the main AWS mechanisms for granting and controlling permissions to resources. While far from comprehensive, this overview should help provide context for the rest of the article. We strongly recommend learning more about these and other mechanisms from the AWS documentation and, better yet, working in the environment itself.
The basic and most common mechanism for granting permissions to cloud resources in AWS is the Identity and Access Management (IAM) service. AWS IAM, which recently celebrated its 10th birthday, lets users attach policies to identities such as users or roles to define: 1) to which resource an identity can have access; and 2) what actions the identity can perform on the resource. In AWS, it is common to use a wildcard (*) to define multiple actions, resources or identities in a single statement. You can also apply conditions to limit a policy’s scope to certain criteria, such as a tag applied on a resource or identity.
An AWS policy can be managed - that is, controlled as a separate object and applied to several identities. A managed policy can be AWS managed (controlled and managed by AWS, with the client controlling where it can be applied) or customer managed (the administrator of the AWS environment creates and manages the object)*.
AWS also allows to create inline policies, which are policies that are dedicated to and used by a specific identity. Inline policies are fairly hard to control and manage.
*As per a previous post, we discourage use of managed policies as they often lead to creation of excessive permissions, generating undue risk.
Resource Based Policies
Other than IAM policies, some AWS resources support creation of a resource based policy (see this AWS document which, among other things, specifies which services support such policies). Resource based policies are configured and attached to the resource itself; they define the identities that can access the resource and the kind of access. A good use case for resource based policies is, for example, to allow access to external identities - i.e. identities from a different AWS account than the account the resource is in. This is something an IAM policy on its own can’t do, since these permissions must be granted by someone who administers the resource.
A permission boundary (PB) is a mechanism for setting a managed policy as the upper limit of what an identity such as an IAM user or an IAM role can do. Setting this policy as a PB doesn’t actually provide the identity with any kind of permissions - it simply sets a limitation on what other IAM policies (note that this mechanism applies to more than resource based policies) granted to the identity can allow. If a permission is not allowed by the PB set on an identity, an IAM policy attached to that identity won’t be able to grant it, either.
Only one permission boundary can be set for each identity.
Service Control Policies
In certain cases, organizations would like to set a limitation similar to a PB on the account level, or possibly even several accounts. AWS offers a tool called Organizations that allows an administrator to centrally manage AWS accounts. This Organizations tool can also be used to apply a “Service Control Policy” (SCP). These SCPs are very similar to a PB - they set a limit on what policies an identity within the applicable account or accounts can perform, without actually granting the permissions themselves. This policy is configured across the account or accounts. It is possible to limit the SCP using a condition, most commonly using a condition key such as 1) aws:ResourceTag, to limit the resources that the SCP would apply or 2) aws:PrincipalTag, to limit the identities to which it would apply. An SCP could also be set on specific resources / groups of resources using a wildcard.
It’s important to note two differences between an SCP and a PB:
- Unlike a PB, an SCP can also limit a resource based policy (given it’s applied on the same account)
- Opposed to a PB, for which AWS allows only one per identity, you can apply several SCPs to the same AWS account - directly or via the Organizational Unit (OU) to which it belongs in AWS Organizations
The full picture is in fact more complicated as AWS has other mechanisms not in the scope of this article, such as session policies, that are more obscure. For a more complete review of these mechanisms and the evaluation logic of AWS, please refer to the AWS documentation.
However, you may have realized by now that it can be quite challenging to process the combination of objects produced by these mechanisms to assess what AWS allows an identity to do - or what identities have access, and what kind of access, to each resource. It’s even harder to decipher if current access can be diminished without compromising the business utility of the environment. AWS has some native tools for doing just that - let’s check them out.
As evident from the name, the AWS IAM Policy Simulator tool lets you simulate the effectiveness of the policies applied in the context of an AWS identity (user, role or group), service and resources. It lets you check if access would be granted to a certain identity using a subset or all actions of a selected service, on all or selected resources in the account.
The nice thing about AWS Policy Simulator is that it lets you process the combination of IAM policies, resource-based policies, permission boundaries and SCPs. It has its limitations, which we will later discuss but, taking all these factors into account, is a very useful utility that allows review (with some limitations) of the actual access a given identity has to a given service.
Another important tool is the AWS IAM access advisor, which lets you view the “last accessed” information for each AWS service on each identity. Plainly put, it lets you view the last time an identity actually used its access permissions to each AWS service as well as the policy attached to it that allows the access. For some AWS services, you get a more granular action-level analysis: you can view not just access to the service itself but also the last time the identity used each action in the AWS service it has access to. This insight was originally available for the S3 service only but AWS recently made it available to the IAM, EC2 and Lambda services, as well.
Similarly, IAM access advisor can be used to review usage at the account level for each of the accounts managed by AWS Organizations. You can view access to services by each account and access to services on each SCP for the accounts to which the policy is attached.
Reviewing the last accessed information at the service level and even more so at the action level helps you figure out which permissions an identity actually needs. It is reasonable to assume that if an identity hasn’t used a permission granted to it by a policy for a significant period of time (the length of which depends on the type of service and identity) then it might not actually need it. Using this logic you can refine the permissions granted to identities and drive them toward least privilege access levels.
AWS’s IAM Access Analyzer lets you (again, as the name suggests) analyze the access to resources in your account. AWS created this service to enable detection of access granted to external identities through resource-based policies of certain types. In a previous post, we demonstrated how you can use the IAM Access Analyzer along with EventBridge and CloudWatch to monitor and log into certain location events of external access being granted to KMS keys -- one type of resource that the Access Analyzer supports.
Recently, AWS enhanced Access Analyzer with two interesting capabilities: Access Analyzer preview and CloudTrail based policy generation. The preview capability, which we wrote about previously, predicts if a resource based policy will grant an external identity new access to the resource on which it is to be applied. This is great as it helps you understand before applying a policy if it will pose more risk to a resource.
About a month ago, Access Analyzer made another significant stride toward helping AWS users pursue least privilege policies with its policy generation capability based on CloudTrail logs. This feature lets you review the activity of an identity based on the CloudTrail logs of a specific period, generate a policy allowing only the permissions used during that specific period, and attach it for use in place of the policies already in place. As we will discuss below, this capability- much like Policy Simulator and access advisor - has its limitations but its approach is in the right place as the only way to determine in a validated way what policy an identity should have is by reviewing what it actually does.
Where do Access Analyzer and the other AWS tools for facilitating least privilege access described here come up short? Let’s find out.
The Case for Automated Analysis
The AWS tools covered here, while useful for some scenarios, have limitations derived from their current implementation and the inherent way in which they operate. We’ll first look at the kind of problems these tools can’t solve and then discuss common challenges that native cloud service provider tools can’t solve due to their very nature.
Where Policy Simulator Falls Short
Probably the most significant gap in the way Policy Simulator operates is by its inability to track the assumption of roles as a way to access permissions. In AWS, a role can be assumed by a different identity (e.g. an IAM user or even a different IAM role) and, once assumed, the permissions granted to the role can be used by the assuming identity. This means that to effectively decide if a resource can be accessed by an identity you have to determine if it can be accessed by any of the roles the identity can assume. This is not an assessment that policy simulator does; the tool therefore may have substantial blind spots in determining if an identity can use certain permissions on a resource.
Another way in which Policy Simulator is lacking is that, according to AWS’s documentation, it can’t “test AWS Organizations service control policies (SCPs) with global condition keys.” While the documentation mentions this inability almost casually, it’s a very significant one since global condition keys such as aws:PrincipalTag (used to classify identities) and aws:ResourceTag (used to classify resources) are very useful when creating SCPs which are meant to apply to specific parts of an AWS account. In addition, from personal experience, testing SCPs that limit access to a specific resource is not as reliable as one might expect: while the SCP itself works, Policy Simulator sometimes reports the resource as still accessible.
Finally, while Policy Simulator allows for it, testing of resource-based policies is applicable only when you test access to the specific resource itself. If you don’t test the specific resource (let’s say you choose to test access to all resources in an account by specifying “*”), Policy Simulator will not take the resource-based policy into account.
Where Access Analyzer Falls Short
As mentioned before, IAM Access Analyzer has made significant strides toward being useful in helping AWS users practice least privilege policy. But it has a long way to go to being fully effective at this task.
First of all, for external access - access analyzer is limited to certain types of resources where it can analyze their resource-based policy.
Second, when an external account has access to an IAM Role - you won’t be notified when the administrator on the external account has provided access to the role to users in the external account or when policies attached to the role change and provide it with access to more resources or more sensitive actions in your account.
Also, while the recent AWS feature of analyzing CloudTrail logs to generate policies based on actual activity definitely has a good approach, the enhancement comes with limitations that make its use at a relevant scale difficult. You can only make an assessment for an identity going back 90 days and only to a limited CloudTrail log size of 25 GB. Perhaps the most crucial limitation is that you can only generate five policies a day per account. This means that if you have an average size environment that holds about 400 different identities it would take you about 3 months to finish one round of assessing them all. We should also mention that this feature is currently not enabled for groups even though groups, as a very prominent way of "grouping" identities and granting them permissions in a unified fashion, require analysis of this kind.
Where Access Advisor Falls Short
While the AWS access advisor tool provides very useful information, its main limitation is in its lack of granularity. It’s almost needless to say that, when it comes to least privilege access analysis, reporting last time access to a service is inadequate. If an identity has full access to a service but uses only one of its functions, that’s about as risk prone as if it weren’t using it at all. Access advisor currently offers action level information for only four services: S3, IAM, EC2 and Lambda. We contend that even action level access is not enough to determine the least privilege policy required for an identity. To significantly limit the blast radius from a security breach, least privilege access must be enforced at the resource level - that is, the policy must specify the exact resources to which access needs to be given.
For example, if an identity has read and write access to all the S3 buckets in an account, that entitlement might (and probably will) include access to sensitive client and/or employee information. Imagine a situation in which a web server needs to be able to read from a bucket holding configuration information and write to a bucket holding logs however has this kind of excessive permissions policy in place. AWS access advisor would report that it constantly uses read/write actions (such as s3:GetObject and s3:PutObject) but will not know or report that it uses them only for a very limited number of buckets. If the web server is compromised, the malicious actor will have access to all the buckets in the environment. With better management of the permissions granted to the web server, the fallout from such a breach can be much less catastrophic.
In addition, AWS access advisor can have even more acute granularity limitations when using AWS Access Analyzer to analyze a role involving federated users. You federate users using a role through which multiple users, which are identified against the identity provider, assume in order to access the cloud based resources that the role permits access to. Access advisor is able to present only the services and, for services that support action-level analysis, the actions that the role accessed. That is, if any user federated through the role accessed a service, AWS access advisor will report the role accessed the service / action. You will not be able to differentiate between users to understand which user actually needs access to which AWS service. To make this kind of distinction, you will need to extensively analyze CloudTrail logs yourself - a scenario we will discuss next. We’ve actually written extensively about the challenges that federation poses to least privilege - feel free to read up on it.
The Underlying Benefits of Using An Automated Analysis Platform
The tools we reviewed in this article are a good place to start if you want to experiment and even gain a bit more control of specific identities and the access they have to resources in your cloud environment. However, if you are looking for an effective approach to the challenge of achieving least privilege access in a cloud environment in general, and in AWS in particular, a dedicated automated analysis platform that continuously analyzes the configurations and logs in your environment to understand which permissions are granted to which permissions - and which are actually required - is probably the way to go, for various reasons.
The first and probably most significant advantage that an identifies-first cloud infrastructure security platform like Ermetic can provide is the ability to review ALL identities in an environment and provide a clear overview of the current state of privileges in an environment. This is necessary to do because it only takes one identity with excessive permissions to pose a great risk to an environment and, more often than not, the identities that pose the most risk are those you don’t suspect. Analyzing all the identities in an environment allows you to understand which pose the most risk and are the most crucial to address - and take care of them first. While cloud native tools can help you focus on specific identities in a one-at-a-time manner, using them at scale is very difficult. Even if you use AWS’s API, which is pretty robust, creating, deploying and maintaining software that does the legwork of gathering, compiling and analyzing this kind of information in all its complexity and scope is an undertaking most companies can’t handle as a side project. It’s also important to note that if your company, like many today, has a multi-cloud strategy, the Ermetic platform provides the same type of analysis in the same console for Azure and GCP as well as AWS.
In addition to the scale involved in solving the problem of granting least privilege access to identities, it’s important to keep in mind that cloud environments are among the most dynamic and agile computing infrastructures in existence. New resources are added all the time, new identities pop up and job functions change frequently. Having least privilege access policies is not a “one off” type of task. Even if, theoretically, a manual or even semi-automatic analysis approach using cloud native tools and/or cloud provider APIs was practical - the necessity of redoing it almost every day to stay current makes it a Herculean task that most security teams cannot find the resources for. A platform such as Ermetic uses automation to keep the analysis fresh and always presents the current state of excessive permissions in the environment amid changes.
Having excessive permissions on identities is usually just one side of the equation. On their own, excessive permissions might not be that urgent to deal with (though obviously worth detecting and taking care of). However when part of a toxic combination that is, combined with attributes that make the identity more prone to be exploited by a malicious actor, such as an IAM user with access keys, excessive permissions may become a great and even immediate threat to your sensitive data or business continuity. Native tools such as by AWS may allow limited analysis of the IAM state for an identity. But it’s up to you to combine this information with data from more sources, such as network configuration, access configuration and even vulnerability exposure, to understand how pressing it is to deal with an identity’s level of permissions.
As security professionals we all know that prioritizing is probably the most important action toward making best use of our budget and people resources. Looking at identities in a vacuum simply doesn’t lend itself to such prioritization.
As we’ve seen from the examples here, the granularity required to effectively determine least privilege policy is sometimes just out of reach of the native AWS tools. Ermetic displays excessive permissions at the finest granularity and also provides rightsized, resource-level policies that you can apply that limit an identity to performing only the actions it needs for its business function. It does this by, among other things, analyzing CloudTrail logs to determine the actions it actually performs -- and can do so at any reasonable learning time you define.
Finally, performing this kind of deep analysis into CloudTrail logs allows Ermetic to make a clear distinction between federated users from an identity provider - even if they all use the same role to access the cloud resources in your environment. Figure 11 shows an example of analysis done on a specific federated user, the permissions it has access to and which of them are excessive. This kind of insight is nearly impossible to obtain using out-of-the-box native tools and by parsing CloudTrail logs manually.
If you want to learn more about how Ermetic can help solve the least privilege access policies challenge in your environment, at scale and with granularity, automation, and context, feel free to take our product for a test run.