fbpx

How to prioritise the results of the IAM Access Analyzer

AWS Identity and Access Management (IAM) Access Analyzer is an important tool in your journey towards least privilege access. You can use IAM Access Analyzer access previews to preview and validate public and cross-account access before deploying permissions changes in your environment.

 <p>For the permissions already in place, one of IAM Access Analyzer’s capabilities is that it helps you identify resources in your <a href="https://aws.amazon.com/organizations/" target="_blank" rel="noopener">AWS Organizations</a> organization and AWS accounts that are shared with an external entity.</p> <p>For each external entity that has access to a resource in your account, IAM Access Analyzer generates a <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-work-with-findings.html" target="_blank" rel="noopener">finding</a>. Findings display information about the resource and the policy statement that generated the finding, with details such as the list of actions in the policy granting access, level of access, and conditions that allow the access. You can review the findings to determine if the access is intended or unintended.</p> <p>As your use of AWS services grows and the number of accounts in your organization increases, the number of findings that you have might also increase. To help reduce noise and allow you to focus on unintended access findings, you can filter findings and create archive rules for intended access.</p> <p>This blog post provides step-by-step guidance on how to get started with IAM Access Analyzer findings by using different filtering techniques that can help you filter approved use cases that result in access findings. For example, you might see a finding generated for an S3 bucket that hosts images for your website and thus allows public access, as approved by your organization, apply a filter so that you can concentrate on unintended access. IAM Access Analyzer offers a wide range of filters; for a complete list, see the <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-findings-filter.html" target="_blank" rel="noopener">IAM documentation</a>.</p> <p>In this post, we also share example archive rules for approved use cases that result in access findings. Archive rules automatically archive new findings that meet the criteria you define when you create the rule. You can also apply archive rules retroactively to archive existing findings that meet the archive rule criteria. Finally, we have included an example implementation of <a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-accessanalyzer-analyzer-archiverule.html" target="_blank" rel="noopener">archive rules</a> using an <a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener">AWS CloudFormation</a> template.</p> <h2>IAM Access Analyzer findings overview</h2> <p>To get started, create an analyzer for your entire organization or your account. The organization or account that you choose is known as the <em>zone of trust</em> for the analyzer. The zone of trust determines the type of access that IAM Access Analyzer considers to be trusted. IAM Access Analyzer continuously monitors to identify resource policies, access control lists, and other access controls that grant public or cross-account access from outside the zone of trust, and generates findings. For this blog post, we’ll demonstrate an organization as the zone of trust, showcasing findings from a large-scale, multi-account AWS deployment.</p> <h2>Prerequisites</h2> <p>This blog post assumes that you have the following in place:</p> <ul> <li>IAM Access Analyzer is enabled in your organization or account in the AWS Regions where you operate. For more details on how to enable IAM Access Analyzer, see <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html#access-analyzer-enabling" target="_blank" rel="noopener">Enabling IAM Access Analyzer</a>.</li> <li>Access to the <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-getting-started.html#access-analyzer-permissions-awsmanpol" target="_blank" rel="noopener">AWS Organizations management account</a> or to a member account in the organization with delegated administrator access for creating and updating IAM Access Analyzer resources.</li> </ul> <h2>How to filter the findings</h2> <p>To start filtering your findings and create archive rules, you should complete the following steps:</p> <ol> <li>Review public access findings</li> <li>Filter by removing permissions errors</li> <li>Filter for known identity providers</li> <li>Filter cross-account access from trusted external accounts</li> </ol> <p>We’ll walk you through each step.</p> <h2>1. Review public access findings</h2> <p>Some AWS resources allow public access on the resource by means of a resource-based policy—for example, an <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html" target="_blank" rel="noopener">Amazon Simple Storage Service (Amazon S3) bucket policy</a> that has the <span>“Principal:*”</span> permission added to its bucket policy. For resources such as <a href="https://aws.amazon.com/ebs/" target="_blank" rel="noopener">Amazon Elastic Block Store (Amazon EBS)</a> snapshots, you can share these by using a flag on the resource permission. IAM Access Analyzer looks for such sharing and reports it in the findings.</p> <p>From the global report, you can generate a list of resources that allow public access by using the <strong>Public access: true</strong> query in the IAM console.</p> <p>The following is an example of an <a href="https://aws.amazon.com/cli/" target="_blank" rel="noopener">AWS Command Line Interface (AWS CLI)</a> command with <a href="https://awscli.amazonaws.com/v2/documentation/api/latest/reference/accessanalyzer/list-findings.html" target="_blank" rel="noopener">public access as “true”</a>. Replace <span></span> with the Amazon Resource Name (ARN) of your <a href="https://us-east-1.console.aws.amazon.com/access-analyzer/home?region=us-east-1#/analyzers" target="_blank" rel="noopener">analyzer</a>.</p> <p> <code>aws accessanalyzer list-findings --analyzer-arn  --filter isPublic={"eq"="true"}</code> </p> <h3>Is the public access intended?</h3> <p>If the access is intended, you can archive the findings by creating an archive rule using the <a href="https://aws.amazon.com/console/" target="_blank" rel="noopener">AWS Management Console</a>, <a href="https://docs.aws.amazon.com/cli/latest/reference/accessanalyzer/create-archive-rule.html" target="_blank" rel="noopener">AWS CLI</a>, or <a href="https://docs.aws.amazon.com/access-analyzer/latest/APIReference/API_CreateArchiveRule.html" target="_blank" rel="noopener">API.</a> When you archive a security finding, IAM Access Analyzer removes it from the <strong>Active</strong> findings list and changes its status to <strong>Archived</strong>. For instructions on how to automatically archive expected findings, see <a href="https://aws.amazon.com/blogs/security/how-to-automatically-archive-expected-iam-access-analyzer-findings/" target="_blank" rel="noopener">How to automatically archive expected IAM Access Analyzer findings</a>.</p> <h3>Example: Known S3 bucket that hosts public website images</h3> <p>If you have resources for which public access is expected, such as an S3 bucket that hosts images for your website, you can add an archive rule with <strong>Resource</strong> criteria equal to the bucket name, as shown in Figure 1.</p> <div id="attachment_29176" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29176" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img1-4-1024x683-1.png" alt="Figure 1: Create IAM Access Analyzer archive rule using the console" width="760" class="size-large wp-image-29176"> <p id="caption-attachment-29176" class="wp-caption-text">Figure 1: Create IAM Access Analyzer archive rule using the console</p> </div> <h3>Is the public access unintended?</h3> <p>If the finding results from policies that were misconfigured to allow unintended public access, you can constrain the access by using <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html" target="_blank" rel="noopener">AWS global condition context keys</a> or a specific IAM principal ARN. The findings show the account and resource that contain the policy.</p> <p>For example, if the finding shows a misconfigured S3 bucket, the following policy shows how you can modify the S3 bucket policy to only allow IAM principals from your organization to access the bucket by using the <span>PrincipalOrgID</span> condition key. Replace <span></span> with the name of your S3 bucket, and <span></span> with your organization ID.</p> <div class="hide-language"> <pre><code class="lang-text">{

“Version”:”2008-10-17″, “Id”:”Policy1335892530063″, “Statement”:[ { “Sid”:”AllowS3Access”, “Effect”:”Allow”, “Principal”:”“, “Action”:”s3:“, “Resource”:[ “arn:aws:s3:::”, “arn:aws:s3:::/” ], “Condition”:{ “StringEquals”:{ “aws:PrincipalOrgID”:”” } } } ]}

 <h2>2. Filter by removing permissions errors</h2> Before you further investigate the IAM Access Analyzer findings, you should make sure that IAM Access Analyzer has enough permissions to access the resources in your accounts to be able to provide the analysis.</p> <p>IAM Access Analyzer uses an AWS <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role" target="_blank" rel="noopener">service-linked role</a> to call other AWS services on your behalf. When IAM Access Analyzer analyzes a resource, it reads resource metadata, such as a resource-based policy, access control lists, and other access controls that grant public or cross-account access. If the policies don’t allow an IAM Access Analyzer role to read the resource metadata, it generates an <strong>Access Denied</strong> error finding, as shown in Figure 2.</p> <div id="attachment_29177" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29177" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img2-4-1024x120-1.png" alt="Figure 2: IAM Access Analyzer access denied error example" width="760" class="size-large wp-image-29177" /> <p id="caption-attachment-29177" class="wp-caption-text">Figure 2: IAM Access Analyzer access denied error example</p> </div> <p>To view these error findings from the <a href="https://us-east-1.console.aws.amazon.com/access-analyzer/home?region=us-east-1#/findings" target="_blank" rel="noopener">IAM Access Analyzer console</a>, filter the findings by using the <strong>Error: Access Denied</strong> property.</p> <h3>Resolution</h3> <p>To resolve the access issue, make sure that the IAM Access Analyzer <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-using-service-linked-roles.html#create-slr" target="_blank" rel="noopener">service-linked role</a> is not denied access. Review the resource-based policy attached to the resource that IAM Access Analyzer isn’t able to access. For a list of services that support resource-based policies, see the <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html" target="_blank" rel="noopener">IAM documentation</a>.</p> <p>For example, if the analyzer can’t access an <a href="https://aws.amazon.com/kms/" target="_blank" rel="noopener">AWS Key Management Service (AWS KMS)</a> key because of an explicit deny, add an exception for the IAM Access Analyzer service-linked role to the policy statement, similar to the following. Make sure that you change the <span></span> to your account id.</p> <table width="100%"> <tbody> <tr> <td width="50%"><strong>Before</strong></td> <td width="50%"><strong>After</strong></td> </tr> <tr> <td width="50%"> <div class="hide-language"> <pre class="unlimited-height-code"><code class="lang-text">{

“Sid”:”Deny unintended access to KMS key”, “Effect”:”Deny”, “Principal”:”

“, “Action”:[ “kms:DescribeKey”, “kms:GetKeyPolicy”, “kms:List” ], “Resource”:”“, “Condition”:{ “ArnNotLikeIfExists”:{ “aws:PrincipalArn”:[ “arn:aws:iam:::role/” ] } }}

 <td width="50%"> <div class="hide-language"> <pre class="unlimited-height-code"><code class="lang-text">{

“Sid”:”Deny unintended access to KMS key”, “Effect”:”Deny”, “Principal”:”

“, “Action”:[ “kms:DescribeKey”, “kms:GetKeyPolicy”, “kms:List” ], “Resource”:”“, “Condition”:{ “ArnNotLikeIfExists”:{ “aws:PrincipalArn”:[ “arn:aws:iam:::role/aws-service-role/access-analyzer.amazonaws.com/AWSServiceRoleForAccessAnalyzer”,”arn:aws:iam::*:role/” ] } }}

 <h2>3. Filter for known identity providers</h2> <p>With <a href="https://wiki.oasis-open.org/security" target="_blank" rel="noopener">SAML 2.0</a> or <a href="https://openid.net/connect/" target="_blank" rel="noopener">Open ID Connect (OIDC)</a>—which are open federation standards that many identity providers (IdPs) use—users can log in to the console or call the AWS API operations without you having to create an IAM user for everyone in your organization.</p> <p>To set up federation, you must perform a one-time configuration so that your organization’s IdP and your account trust each other. To configure this trust, you must register AWS as a service provider (SP) with the IdP of your organization and set up metadata and key exchange.</p> <p>The role or roles that you create in IAM define what the federated users from your organization are allowed to use on AWS. When you create the trust policy for the role, you specify the SAML or OIDC provider as the <code>Principal</code>. To only allow users that match certain attributes to access the role, you can scope the trust policy with a <code>Condition.</code></p> <h3>Example 1: Federation with Okta </h3> <p>Let’s walk through an example that uses Okta as the IdP. Although access to a trusted IdP is intended, IAM Access Analyzer creates a finding for an IAM role that has trust policy granting access to a SAML provider because the trust policy allows access outside of the known zone of trust for the analyzer. You will see findings created for the IAM role granting access to Okta using the IAM trust policy, as shown in Figure 3.</p> <div id="attachment_29187" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29187" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img3.jpg" alt="Figure 3: IAM Access Analyzer identity provider finding example" width="760" class="size-full wp-image-29187" /> <p id="caption-attachment-29187" class="wp-caption-text">Figure 3: IAM Access Analyzer identity provider finding example</p> </div> <h3>Resolution </h3> <p>Setting access through SAML providers is a privileged operation, so we recommend that you analyze each finding to decide if an exception is acceptable. If you approve of the SAML-provided access setup, you can implement an archive rule to archive such findings with conditions for federation used in combination with your SAML provider. The filter for the <strong>Federated User</strong> rule depends on the name that you gave to the SAML IdP in your federation setup. For example, if your SAML IdP name is Okta, the rule should have a filter for <span>arn:aws:iam::<span></span>:saml-provider/Okta</span>, where <span></span> is your account number, as shown in Figure 4.</p> <div id="attachment_29188" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29188" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img4-4-1.png" alt="Figure 4: Archive rule example for using an IdP-related finding" width="760" class="size-full wp-image-29188" /> <p id="caption-attachment-29188" class="wp-caption-text">Figure 4: Archive rule example for using an IdP-related finding</p> </div> <blockquote> <p><strong>Note</strong>: To include additional values for a multi-account setup, use the <strong>Add another value</strong> filter.</p> </blockquote> <h3>Example 2: IAM Identity Center</h3> <p>With <a href="https://aws.amazon.com/iam/identity-center/" target="_blank" rel="noopener">AWS IAM Identity Center (successor to AWS Single Sign-On)</a>, you can manage sign-in security for your workforce. IAM Identity Center provides a central place to define your<a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html" target="_blank" rel="noopener"> permission sets</a>, assign them to your users and groups, and give your users a portal where they can access their assigned accounts.</p> <p>With IAM Identity Center, you manage access to accounts by creating and assigning<a href="https://docs.aws.amazon.com/singlesignon/latest/userguide/permissionsetsconcept.html" target="_blank" rel="noopener"> permission sets</a>. These are <a href="https://aws.amazon.com/iam/" target="_blank" rel="noopener">IAM</a> role templates that define (among other things) which policies to include in a role. When you create a permission set in IAM Identity Center and associate it to an account, IAM Identity Center creates a role in that account with a trust policy that allows a federated IdP as a principal — in this case, IAM Identity Center.</p> <p>IAM Access Analyzer generates a finding for this setup because the allowed access is outside of the known zone of trust for the analyzer, as shown in Figure 5.</p> <div id="attachment_29189" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29189" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img5.jpg" alt="Figure 5: IAM Access Analyzer finding example for IAM Identity Center" width="760" class="size-full wp-image-29189" /> <p id="caption-attachment-29189" class="wp-caption-text">Figure 5: IAM Access Analyzer finding example for IAM Identity Center</p> </div> <p>To filter this finding, you need to implement an archive rule.</p> <h3>Resolution</h3> <p>You can implement an archive rule with conditions for federation used in combination with IAM Identity Center as the SAML provider. The roles created by IAM Identity Center in member accounts use a reserved path on AWS: <span>arn:aws:iam::<span></span>:role/aws-reserved/sso.amazonaws.com/</span>. Hence, you can create an archive rule with a filter that contains <span>:saml-provider/AWSSSO</span> in the <strong>Federated User</strong> name and <span>aws-reserved/sso.amazonaws.com/</span> in the <strong>Resource</strong>, as shown in Figure 6.</p> <div id="attachment_29190" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29190" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img6.jpg" alt="Figure 6: Archive rule example for IAM Identity Center generated findings" width="760" class="size-full wp-image-29190" /> <p id="caption-attachment-29190" class="wp-caption-text">Figure 6: Archive rule example for IAM Identity Center generated findings</p> </div> <h2>4. Filter cross-account access findings from trusted external accounts</h2> <p>We recommend that you identify and document accounts and principals that should be allowed access outside of the zone of trust for IAM Access Analyzer.</p> <p>When a resource-based policy attached to a resource allows cross-account access from outside the zone of trust, IAM Access Analyzer generates cross-account access findings.</p> <h3>Is the cross-account access intended?</h3> <p>When you review cross-account access findings, you need to determine whether the access is intended or not. For example, you might have access provided to your auditor’s account or a partner account for visibility and monitoring of your AWS applications.</p> <p>For trusted external accounts, you can create an archive rule that includes the AWS account in the criteria for the rule. Figure 7 shows an example of how to create the archive rule for a trusted external account (<span>EXTERNAL_ACCOUNT_ID</span>). In your own rule, replace <span>EXTERNAL_ACCOUNT_ID</span> with the trusted account id.</p> <div id="attachment_29191" class="wp-caption aligncenter"> <img aria-describedby="caption-attachment-29191" src="https://www.infracom.com.sg/wp-content/uploads/2023/04/img7.jpg" alt="Figure 7: Archive rule example for trusted account findings" width="760" class="size-full wp-image-29191" /> <p id="caption-attachment-29191" class="wp-caption-text">Figure 7: Archive rule example for trusted account findings</p> </div> <h3>Is the cross-account access unintended?</h3> <p>After you have archived the intended access findings, you can start analyzing the findings initiated from unintended access. When you confirm that the findings show unintended access, you should take steps to remove the access by altering or deleting the policy or access control that granted access. You can expand the solution outlined in the blog post <a href="https://aws.amazon.com/blogs/security/automate-resolution-for-iam-access-analyzer-cross-account-access-findings-on-iam-roles/" target="_blank" rel="noopener">Automate resolution for IAM Access Analyzer cross-account access findings on IAM roles</a> by adding an explicit deny statement.</p> <p>You can also use <a href="https://aws.amazon.com/cloudtrail" target="_blank" rel="noopener">AWS CloudTrail</a> to track API calls that could have changed access configuration on your AWS resources.</p> <h2>Deploy IAM Access Analyzer and archive rules with a CloudFormation template</h2> <p>In this section, we demonstrate a sample <a href="https://aws.amazon.com/cloudformation/" target="_blank" rel="noopener">CloudFormation</a> template that creates an IAM access analyzer and archive rules for findings that are created for identified intended access to resources.</p> <blockquote> <p><strong>Important:</strong> When you create an archive rule using the AWS console, the existing findings and new findings that match criteria mentioned in the rules will be archived. However, archive rules created through CloudFormation or the AWS CLI will only archive the new findings that meet the criteria defined. You need to perform the <a href="https://docs.amazonaws.cn/en_us/access-analyzer/latest/APIReference/API_ApplyArchiveRule.html" target="_blank" rel="noopener">access-analyzer:ApplyArchiveRule</a> API after you create the archive rule to archive existing findings as well.</p> </blockquote> <p>The sample CloudFormation template takes the following values as inputs and creates archive rules for findings that are created for identified intended access to resources shared outside of your zone of trust for the specified analyzer:</p> <ul> <li>Analyzer name</li> <li>Zone of trust</li> <li>Known public S3 buckets, if you have any (for example, a bucket that hosts public website images).<br /><blockquote> <p><strong>Note</strong>: We use S3 buckets as an example. You can edit the rule to include resource types that are supported by IAM Access Analyzer, if public access is intended.</p> </blockquote> </li> <li>Trusted accounts — AWS accounts that don’t belong to your organization, but you trust them to have access to resources in your organization</li> <li>SAML provider — The SAML provider approved to have access to your resources<br /><blockquote> <p><strong>Note</strong>: If you don’t use federation, you can remove the rule <span>SAMLFederatedUsers</span>.</p> </blockquote> </li> </ul> <pre class="unlimited-height-code"><code class="lang-yaml">AWSTemplateFormatVersion: 2010-09-09

Description: >+ Sample CloudFormation template creates archive rules for findings created for resources shared outside of your zone of trust for specified analyzer.Metadata: AWS::CloudFormation::Interface: ParameterGroups: – Label: default: Define Configuration Parameters: – AccessAnalyzerName – ZoneOfTrust – KnownPublicS3Buckets – TrustedAccounts – SAMLProviderParameters: AccessAnalyzerName: Description: Provide name of the analyzer you would like to create archive rules for. Type: String ZoneOfTrust: Description: Select the zone of trust of AccessAnalyzer AllowedValues: – ACCOUNT – ORGANIZATION Type: String KnownPublicS3Buckets: Description: List of comma-separated known S3 bucket arns, that should allow public access Example – arn:aws:s3:::DOC-EXAMPLE-BUCKET,arn:aws:s3:::DOC-EXAMPLE-BUCKET2 Type: CommaDelimitedList TrustedAccounts: Description: List of comma-separated account IDs, that do not belong to your organization but you trust them to have access to resources in your organization. [Example – Your auditor’s AWS account] Type: List TrustedFederationPrincipals: Description: List of comma-separated trusted federated principals that are able to assume roles in your accounts. [Example – arn:aws:iam::012345678901:saml-provider/Okta, arn:aws:iam::1111222233334444:saml-provider/Okta] Type: CommaDelimitedListResources: AccessAnalyzer: Type: AWS::AccessAnalyzer::Analyzer Properties: AnalyzerName: ${AccessAnalyzerName}-${AWS::Region} Type: ZoneOfTrust ArchiveRules: – RuleName: ArchivePublicS3BucketsAccess Filter: – Property: resource Eq: KnownPublicS3Buckets – RuleName: AccountAccessNecessaryForBusinessProcesses Filter: – Property: principal.AWS Eq: TrustedAccounts – Property: isPublic Eq: – “false” – RuleName: SAMLFederatedUsers Filter: – Property: principal.Federated Eq: TrustedFederationPrincipals

To access this sample template, get the document IAMAccessAnalyzer. yaml from Amazon S3.

Conclusion

In this blog posting, you learned how to start with IAM Access Analyzer findings, strain them based on the level of exposure given outside of your area of confidence, and produce record rules for intended access findings. By using various screening techniques to remediate intended entry findings, you can rely on unexpected entry.

To get this answer further, we recommend that you consider automating the quality of unexpected cross – account IAM roles found by IAM Access Analyzer by adding a grant declaration to the IAM role’s’s trust policy. You can also include abilities like an approval process to resolve the seeking to suit your organization’s’s procedure requirements.

Finally, we suggest that you use IAM Access Analyzer get previews to preview and evaluate people and cross – account access before deploying permissions changes in your environment.

If you have comments about this article, post feedback in the Comments sections below. If you have doubts about this article, get AWS Support.

Need more AWS Security message? Become our Twitter follower.

 <!-- '"` -->