DEV Community

Cover image for AWS re:Invent 2025 - IAM Access Analyzer Deep Dive: From Configuration to Remediation (SEC340)
Kazuya
Kazuya

Posted on

AWS re:Invent 2025 - IAM Access Analyzer Deep Dive: From Configuration to Remediation (SEC340)

🦄 Making great presentations more accessible.
This project aims to enhances multilingual accessibility and discoverability while maintaining the integrity of original content. Detailed transcriptions and keyframes preserve the nuances and technical insights that make each session compelling.

Overview

📖 AWS re:Invent 2025 - IAM Access Analyzer Deep Dive: From Configuration to Remediation (SEC340)

In this video, Jeremiah Dunham and Mitch Beaumont provide a comprehensive deep dive into IAM Access Analyzer, covering its configuration and remediation workflows. They explain the three analyzer types: External Access Analyzer (free, detects cross-account access), Unused Access Analyzer (identifies unused permissions using CloudTrail logs), and Internal Access Analyzer (maps all access paths to critical resources). The session demonstrates automated reasoning technology that provides deterministic security analysis, unlike probabilistic AI. They showcase live demos of creating analyzers via CLI, managing findings with archive rules, and implementing preventative controls using custom policy checks integrated with AWS CodePipeline. A notable demonstration includes using Amazon Bedrock to automatically generate prescriptive remediation guidance in GitHub issues, significantly shortening the feedback cycle between developers and security teams. Best practices include starting with longer tracking periods for unused access, using meaningful naming conventions, and applying internal analyzers only to critical resources due to computational costs.


; This article is entirely auto-generated while preserving the original presentation content as much as possible. Please note that there may be typos or inaccuracies.

Main Part

Introduction to IAM Access Analyzer and the Journey to Least Privilege

Welcome, welcome, welcome everyone. Thank you so much for coming to our session. This is SEC 340: IAM Access Analyzer Deep Dive: From Configuration to Remediation. Quick question before I get started. How many of you is this your first session of the conference? Can I see some hands? Yes, thank you for making ours the first. For those of you who have already attended something else, that's great too. Thank you for going and supporting whoever that was.

My name is Jeremiah Dunham. I am a Senior Software Development Manager here at AWS. I'm on stage in front of you talking about IAM Access Analyzer because I lead the IAM Access Analyzer engineering team, so my team builds this product. My name is Mitch Beaumont. I'm a Principal Solutions Architect based in Sydney, Australia, and I get to work with customers on a daily basis, helping them figure out how to assemble the AWS building blocks like IAM Access Analyzer. Hopefully I can bring some of that experience here today and share with you to take home to your own organizations.

Thumbnail 80

Between Mitch and I, as I'm sure you gathered, I understand what's going on behind the scenes of IAM Access Analyzer. I build the product. Mitch works with customers who use it, so between the two of us we should be able to cover pretty much anything you want to know about it. This is a code talk, so we're going to get into some code and some demos and things like that for you. But first we want to level set, so you're going to have to listen to me talk for a few minutes. Here is the agenda. I'm going to talk a little bit about the journey to least privilege, give you an overview of IAM Access Analyzer, talk about automated reasoning, and if you don't know what that is, that's okay. Hopefully you'll know by the time I'm done. Then I'll turn it over to Mitch and we'll code. In fact, before the session I was joking with Mitch that now that we have Claude, I mean who writes code anymore anyway? You just tell the agent and it goes and does it for you.

Thumbnail 140

Thumbnail 160

IAM Access Analyzer. The goal of IAM Access Analyzer as a service is to help you get to least privilege. We talk about the journey to least privilege because it's really a moving target. Access Analyzer is there at all the various stages of the permissions lifecycle as they evolve over time to help you continue to refine and scope things down. Our mental model for doing this is we think of the permissions lifecycle as having three phases: set, verify, and refine. Those are pretty self-explanatory. Basically you create some permissions, then you use Access Analyzer to verify what permissions you have created and make sure that is what you intended. Then finally, if it isn't, you go and refine it, which takes you back to the beginning and so on and so forth.

We have a bunch of different features in Access Analyzer to help you do this. There are five of them listed here. I'm going to talk about each of these in a moment except for policy generation. I'm not going to talk about that too much, so I'll give you the TLDR on that. You basically create a star star type policy for your application while it's in test. You let it run, you let policy generation analyze the logs, and then it recommends a least privileged policy based on the actions that your application took in test. Then you deploy that to production. You don't deploy the star star policy to production. Please don't do that. You deploy the least privileged policy to production.

Thumbnail 240

For the rest of these, I'll get into those in just a second. Our secret sauce, one of the very unique things that we do in IAM Access Analyzer is we use a technology called automated reasoning. It's funny, sometimes people ask me like, hey, is that like AI? No, it is the opposite of AI actually. It's kind of interesting. They both use advanced math, but it's kind of the opposite. Where AI uses probability to predict what will come next, automated reasoning is deterministic. We use mathematical proof to tell you definitively yes, something is possible or no, something is not possible.

Thumbnail 300

That is literally all I'm going to say about that because it's a super deep topic. So you have two options if you want to go deeper. Probably the easier one is the one I'd recommend, which is scan the QR code and go read up on what's there at that link. The second option is go get a PhD in formal logic. Alright, the features that I'm going to talk about that are part of our Access Analyzer, we have three analyzers, three different types of analyzers, and these come in at the verify and refine stage

Three Types of Analyzers: External Access, Unused Access, and Internal Access

You've already deployed permissions, and these are detective controls. They'll look at all the things that you have already deployed and then give you some findings to tell you what's going on. The first, and this is the granddaddy of them all, is the External Access Analyzer. This is a free feature, so please, if you do nothing else after this session, go turn this on. It's free. What External Access Analyzer does is you set the scope, either organization level scope or account level scope, and it will tell you whether there are any resources inside either the account or the organization that have permitted access outside of that zone of trust, either outside of the account or outside of the organization. It will produce all those as findings and you can go through and take some action either by changing the scope to remove that or archiving the findings to say that's what you intended.

Thumbnail 370

The next analyzer that we launched has a little bit different flavor. It's called Unused Access Analyzer. This is the Marie Kondo of analyzers. It helps you get rid of the things that do not bring you joy. Those things are unused permissions, permissions that nobody needs that have actually been granted but are not used. This one is pretty simple. You turn it on and you can set the scope similar to the other one. What it does is look through all the principals in your account or organization, whatever scope you've set, and it will tell you for any given principal whether there are any unused permissions. It will also tell you about any unused access keys or if you have whole roles or whole users that have not been used in some period of time.

Thumbnail 450

The other nice thing that we do is for the unused permissions where you have a role and there are certain permissions in there that have not been used in a long time, we actually use automated reasoning to recommend a policy that you can replace the permissions with, which will now be least privilege. The most recent analyzer type which we launched and reinforced this year, about six months ago, is the complement to External Access, which is Internal Access Analyzer. For this particular one you want to set it on only your most critical AWS resources like S3 buckets or DynamoDB tables, basically things that only a very small number of roles or people should have access to. What it will do is produce a full report of everyone inside your organization that has access to that resource and the nature of their access, meaning what conditions they can access and what particular operations they can perform. Again, only on your most critical resources. This is a very computationally expensive thing to do, so it costs money.

Thumbnail 510

Custom Policy Checks for Preventive Security Controls

So that was on the verify and refine side of the equation. You've already deployed things and you want to look at the things that have been deployed and clean them up. What if you want to prevent unintended things from getting into the environment in the first place? This is at the set phase, and for that we have custom policy checks. The basic idea is they're a set of static APIs that you feed your policies into. In the case of Validate Policy, which is a free API that runs a bunch of AWS best practice checks, it's kind of like a linter for your policies and says here are all the things that your policy does that it probably shouldn't do. Go clean those up.

For the other three APIs, the ones that start with check, these are your best practices, your organizational standards. You would say, for example, I don't think that roles should generally have access to S3 delete bucket. That is not something we typically do, so most people shouldn't have access to that. What we're going to do is use something like CheckAccessNotGranted. We pass in the policy and we see whether the policy attempts to grant S3 delete bucket. If it does, that check fails and then you can take the appropriate action. If it doesn't, then it passes and you're good to go. So those are the options. That's the overview.

Thumbnail 610

Now we're going to let Mitch jump into some code, some demos, and all kinds of things. It's going to be great. Can you see if the stream deck works there in the way we expect it to? Oh, that's awesome. Magic, excellent. Right, we were trying to figure out if it's best for me to stand up, sit down, or hunch over. I'm going to try sitting down to start with and see how that goes. If I start standing up, you'll know I'm not enjoying it.

Configuring and Managing External Access Analyzer: Live Demo and Best Practices

So you've seen and heard from Jeremiah about all of the different analyzers that are available to you. What I'm going to walk you through now is the configuration of those different analyzers, and then Jeremiah, as the engineering leader for the team that builds these things, is going to provide some color and depth on how these things work underneath the hood. We're going to share some best practices for each of the analyzers when it comes to configuration, managing all of the signal that gets generated by these analyzers, and some of the things you can do when it comes to actually responding to and remediating the findings that get generated.

Thumbnail 690

Thumbnail 710

We're going to start with the External Access Analyzer. If Jeremiah said before while he was presenting, there was one thing that everyone needs to do when they leave today—if nothing else they remember. Does anyone remember what that was? Beautiful, good. They're listening. Excellent. So do that. That's probably lesson number one. So, External Analyzer. Hopefully you're all familiar with the AWS Management Console. This is an S3 bucket. It's been labeled "external" because it made it easier to find it amongst my 700 S3 buckets that I have here. We're going to look at this one. I'm in an account at the moment that ends with 4447, that's the end of my account.

What we can see here in the bucket policy for this S3 bucket is it has a principal in the principal property here that is not my account and essentially is allowing S3 GetObject and ListBucket on the resources or the objects that are inside of that. That's not really what I want. Let me take a step back there for a second. There are some valid use cases for having cross-account access. For the purpose of today's session, that's not what I want. You can imagine as you create more S3 buckets, if you're in a large organization with many hundreds or thousands of AWS accounts and each of those having their own S3 buckets, you would want to understand and know when and where there are these kinds of configurations that would potentially permit access to your S3 buckets from entities or principals that are not within your zone of trust—either not within your immediate account or not within your own AWS organization.

Thumbnail 790

Thumbnail 830

So we have an issue here. How do we scale the detection of this kind of thing? That's really where Access Analyzer's External Access comes into play. How do we configure an External Access Analyzer? Well, this is a code talk. I'm going to paste some command line into here, so it's kind of code. This is how you configure it from a command line perspective. We can also configure this from the Management Console or using the SDKs, whatever your preferred approach is. Some really simple configuration options: I want to create a new analyzer, I want to give it a name, and I want to define the type of analyzer—is it account-scoped or organization-scoped? The difference being, if it's account-scoped, it's going to let me know if anything outside of my current account can access my S3 bucket or my resource. If it's organization-scoped, it will let me know if anything outside of the boundary of my organization can access that resource. And then I define the region that I want to deploy it into. I'm going to hit paste and I'm going to hit enter. Very quickly I get a response back with the ARN of the analyzer that's been created. If we go over to the console here now and hit refresh, hopefully we'll see an analyzer created, which we have, so that worked. That was good.

Thumbnail 840

Thumbnail 850

Thumbnail 860

Thumbnail 880

Whilst we wait for a few minutes just for this to start gathering some findings, what I might ask Jeremiah to do now is perhaps provide a little bit of detail on how this works under the covers. Yeah, absolutely. So basically, the way we generate findings, there are kind of two interesting pieces to this. You can't grant cross-account or cross-organization access to a resource without writing a resource policy. So the analyzer starts by pulling the resource policy, and in the case of S3 buckets where they have some kind of legacy things like access control lists, we pull all that stuff as well. And then we run our automated reasoning to basically deduce whether this thing grants external access—yes or no. By external, we mean either public, so we have made some potentially big configuration error and we've granted any untrusted principal access to the bucket, or also granted anybody from another account access.

The second piece to this is that we can also create an organization-scoped analyzer. In order for us to know what access has been granted within or outside the organization, we also have to fetch all of the organization-related metadata, like the organization structure and all the OUs and accounts that are within the organization, so we can determine whether this access is just granted to another account in the org or if it's granted outside.

Thumbnail 920

Thumbnail 950

Thumbnail 970

That brought me just enough time for the analyzers to start gathering some information for me. As luck would have it, one of the very first findings that got generated through the analyzer came up right away. Now it's running and you saw this interactively, right? This was live, and in a matter of seconds we started getting this information. The external bucket that I mentioned I'd misconfigured came up as one of the findings straight away. We can see that there is an external entity, which is the principal that has access. We can see that the sharing has been done, or the access has been granted via the bucket policy. We can also see the different types of access that has been granted through that policy. Really quickly we can start to figure out whether I really want people to access these resources. In this case it's an S3 bucket, but it also can be things like IAM roles as well. We can see down there that we've got some super special roles that are accessible via an external AWS account, so outside of my current scope.

Thumbnail 1020

Over and above just making sure that you enable external access analyzer when you leave here today, there are a few other best practices that are worth keeping in mind when it comes to configuring this and managing it on an ongoing basis. I'm going to hit refresh again, and you can already see we've got 55 findings that have been generated here now. This is a single account, and I don't do much in this particular account. I'm probably going to burn it when I've finished here today. But in an organization with hundreds or thousands of accounts, you can imagine that all of this can be quite overwhelming. The signal to noise ratio gets very, very high.

Thumbnail 1070

One of the things that is quite effective at helping you zero in on the things that are most important is to recognize that there are perhaps some things down here that I know I expect to be configured in this way. Maybe some buckets that I do want to be cross-account accessible, or some roles that I have allowed external third parties to assume so they can do things inside of my account. So how do I remove some of that noise so I can zero in on the things that are most important? Well, the way that you can do that, and this is best practice number one, is to create an archive rule. These archive rules allow you to archive certain types of findings that you don't want to worry about necessarily, because you know that they're supposed to be there.

Thumbnail 1080

Thumbnail 1100

Thumbnail 1120

I'm going to create an archive rule. The first thing I did was create the name and make the name correspond to the thing that I'm trying to archive. I do this just because it makes it easier for the next person that comes along and takes my job when I leave to understand what that rule does, so they know what's happening here. The next thing is that I'm going to set some criteria. I want to archive only if public access is false. I never want to accidentally archive something that is publicly accessible, so I always leave that criteria in there as well. Then the last piece of the criteria is to enter in the name itself of the thing that I want to archive. My role is super special role, as you can see I had a few of those floating around, and they're all part of my administration setup. So I need people to be able to assume them from different accounts. I've got 61 findings that have been generated or discovered as a result of this archive rule now.

Thumbnail 1140

Thumbnail 1160

I can just create that archive rule. What we find then is if I go back to my findings, I get a lot less findings now. I've dropped down from whatever it was, probably 70 odd or more, down to 31 now. Straight away I can start to zero in on the things that are most important to me. I'm going to jump over here and put this on the screen because I wanted to have something for you to perhaps photograph on your phones that might be useful for you to take away. When it comes to things like external access analyzer, as we already said, start with your external access analyzer. Now it's free, it doesn't cost anything, and it can give you a whole bunch of useful insights. Create those archive rules to help you really zero in and remove some of the stuff that you don't need to worry too much about. Make sure you're using good naming standards, both for your archive rules and potentially for your analyzers, but also encourage your colleagues who are creating these IAM resources to give their IAM resources friendly names.

If I hop back to the findings again and I look down here at some of these findings, if I look down here, here's one. This one's called loads of random something. I mean, that doesn't mean anything to me. What does that actually do?

Thumbnail 1220

If my colleagues had given it a name, perhaps this role is a special high-privileged role or something like that, then at least I know what it is and I can take some action, or I know who to go and have a conversation with when I'm trying to remediate those roles.

Thumbnail 1230

Thumbnail 1260

Thumbnail 1270

Let me inspect the findings. If I take a look at that particular one there as well, this more random role, if I click into this. Let me move my console down here a second. So I can see this is the finding that's been generated for this particular role. The role can be assumed by this external entity. It's the STS AssumeRole permission. The name of that role is this super special role itself. If I go down here and find the name of the role and click on this one here, what I can see is that this role is able to be assumed by some external principal. The external analyzer has told me about it. So should I be worried about that? Well, this role was created on October 13th. It's never actually been used, and it has some kind of random permissions down here. I don't know if they're necessarily super useful or not. But at least I can see that the role itself hasn't been used, so it gives me a good next step.

Thumbnail 1290

Thumbnail 1300

Thumbnail 1310

Let me go and speak to the person that I think owns this role. I can also look here at last accessed privileges, and I can see that nothing's been used here at all. So there's a good chance that I can go in and actually delete this role. But I should go and check with the person that owns it first. I can delete it to remove one extra finding from my external access analyzer, which is great. The other benefit to that is that by inspecting a little deeper, understanding whether that role has been accessed recently and whether it's used any of the permissions that have been granted, I can potentially remove that role and save myself 20 cents when we look at enabling the next analyzer, which is the unused access analyzer.

Thumbnail 1330

Thumbnail 1340

Thumbnail 1350

Unused Access Analyzer: Identifying and Remediating Unused Permissions

That's what I'm going to talk to right now. By the way, we will take questions, but we'll do this at the end if that's alright, so we can get through the content first. Jeremiah and I will hang around at the end outside if you want to come and speak to us as well. So that's external. Let's look at the unused access analyzer now. I've already created an unused access analyzer, but I'm going to quickly just show you the console experience for doing that so you understand what that looks like.

Thumbnail 1360

Thumbnail 1370

Thumbnail 1390

It's a principal-based analyzer as Jeremiah said. I'm going to give it a name. Again, back to naming conventions, I get pretty hung up on this, but it's really worth calling these things what they are to make it easy for the next person to come along who picks up your job and understands what you're intending to do there. So I've called it "UnusedAccess-ConsoleAnalyzer-1-day." This is going to look at anything that has permissions or any IAM resources that we're looking at, so principals that haven't been used in the last one day. I've set that to one day because, for the demonstration, we just want to make sure that we can see things and activities. I've given it a name of one day, and I've set my tracking period to one day as well. I've specified the region and the accounts. I've also got the opportunity, if I wanted to, to exclude certain things from this analyzer.

Thumbnail 1400

Thumbnail 1430

Thumbnail 1440

So there might be management accounts that I want to exclude from the analyzer if I'm in a big organization. There also might be a series of IAM roles or principals that I expect to have unused permissions, maybe they're service account related or they're associated with deployment pipelines, that kind of thing. Perhaps they don't run every day or perhaps they run once every three months, that kind of thing. So I want to exclude those from my one-day analyzer. I can add tag metadata into here to say exclude these particular ones from the process. I hit create and then it's going to go ahead and create my unused analyzer for me. Now I'm going to open that up. While I open that up and we wait for the analyzer findings to magically generate, which they have, I'm going to let Jeremiah provide a bit of background on how this analyzer works.

Thumbnail 1470

So as it turns out, in Access Analyzer, there are two very special things that we do. One is automated reasoning, which I already talked about a little bit. The second one is what powers this analyzer, which is we actually process every single access log, so every IAM access log and every CloudTrail log we process so that we can figure this out. It's a lot of data, as you might imagine. Also worth noting, there are some last used APIs in the IAM namespace. Those APIs also use this index that we build from processing all the log data. So because we're good little demo people, we pre-staged a few things here to try and generate some useful and interesting findings. One of those is a Lambda function that we created that has a whole bunch of excessive permissions and really only uses

Thumbnail 1510

Thumbnail 1520

Thumbnail 1530

Thumbnail 1540

Thumbnail 1560

Thumbnail 1570

Thumbnail 1580

Thumbnail 1610

Thumbnail 1630

Thumbnail 1660

Thumbnail 1670

a handful of those, if any. I'm going to look at my Lambda function here quickly and examine the permissions. We can see this Lambda function has permissions to do all the things, really. Actually, all this Lambda function does is list S3 buckets, so it doesn't need to do all of these things. What I'm hoping for in a minute is if the demo gods play nicely, we should be able to see a good example of the power of the unused access analyzer. I'm going to copy that name there and take it across. The finding experience is very similar to what we saw with the external analyzer. You can see there they have finding IDs, we have all of the different finding types, whether it's an unused role or unused permissions, or unused access keys, and I'll talk a bit more about that in a second. What I can do is filter by finding type, or I'm going to do finding type and just do unused permissions. So what we should see, if I scroll down my list here somewhere, do I find my Lambda function? It's not there, let me close that again. Let's go with resource contains. OK, so my Lambda function for some reason isn't there today, which is good. We can try this one here. What we can see is we've got these unused permissions that have been identified in this particular role here. If I go over here and have a look at the unused permissions underneath this particular role, what I can see is I've already got a list of the permissions that this particular role hasn't used. It has a series of permissions, but it doesn't do any of the things that are listed there. In addition to telling me that there are a series of permissions that it isn't using and making some suggestion that I should probably refine those permissions, it also gives me a policy recommendation that I can look at and potentially apply to this particular role that I brought up on the screen here. If I look at preview policy, as Jeremiah said, it's looked at all of the access patterns, all of the logs, and it's said, well this is your existing policy, here is the recommended policy with all of the actions that you're actually using or that this principal is actually using. It's really more of a refined set of permissions, ideally the least privileged. As we go through this journey over time, it will start to understand more about what I am and what I'm not using, and I'll continually get that refinement of policy right down to something that is as least privileged as it needs to be for the thing that it needs to do. Now I talked about creating this at a one day interval for today. What we generally recommend customers do is start with a fairly large tracking period, probably one year or 365 days. The reason for that is because there's going to be a lot less things for you to clean up, hopefully, that haven't been used for 365 days or more. Do that, start there, look for all those things that haven't been used for that long. It's going to be easier to check things off the list. Once you've done that and you've gotten rid of everything that hasn't been used for a year or more, wind it down to 270 days, wind it down to 90 days, and take that iterative approach over the remediation process right down until you get to the point where you're at your happy place.

Thumbnail 1760

Thumbnail 1800

Maybe that's 90 days. 30 days often catches people out because there are some processes that use these principals that perhaps don't run every day or week. Maybe it's a 30 day cycle, and you do have to be super careful when you're going through the process of remediating some of these roles because there can be processes that use these principals that do not run as frequently as you're running the tracking period. There could be a pipeline that deploys patches or updates or transforms data that maybe only runs once every 30 days because it does batch ingestion. You don't want to start deleting roles from the account or removing privileges, only to find out a month later that some critical data transformation pipeline has broken because you've removed those permissions. So best practices for when you're configuring these: start with that one year period, which is really important. Iterate over that and consider putting that time series into the name of the analyzer. When you're looking at all the analyzer findings, you can actually filter by the different names of the analyzer, so you might go, well, I want to look at what hasn't been used for 30 days, what hasn't been used for 70 days or 90 days. Exclude those accounts that you know are probably going to generate findings, which will save you some money, and obviously remove the noise from all the useful signals. When it comes to finding types, we generally recommend that customers start by looking at the most challenging or problematic areas.

Thumbnail 1810

Unused access keys is a really good example. I just showed you quickly there how to filter that. So I can look at an unused access key here. This unused access key appears to not have been used in the last day, at least, probably longer. It's not uncommon for engineers to create access keys for demo purposes and testing purposes. But it's good to know they haven't been used because we can go back to those engineers and say, look, we get you used it for a reason, for part of your project, but let's remove that now because we don't need it to be there anymore.

Thumbnail 1840

You can filter these different finding types, really zeroing it down until you get to the point where you've only got what you need. Getting rid of those unused principles, those rules, those unused permissions, ultimately again saves you money because it won't get analyzed the next time the thing runs. I already mentioned about being careful when it comes to deleting these things because someone might have a principle that is only used once every month or so. Depending on how you're using this and how you want to use the output and the information, you might consider just running this once every six months.

If this is part of an input into an audit cycle you're doing as part of your risk and compliance, this is a compensating control that helps you understand where your risks are. If this is part of a review with auditors or quality assurance people, consider running it every thirty days, every sixty days, every ninety days, or even every six months. Get the results, provide them to whoever needs them, and then delete the analyzers because you will get charged for this. It runs every month, so you get charged per resource or per principal per month. If you're not going to use that information and look at it every day, create it, get the information, delete it, and pass it on to someone else.

Thumbnail 1930

Internal Access Analyzer: Deep Visibility into Critical Resource Access Paths

The only thing to keep in mind when you do that is that the archive rules get deleted along with the analyzer when you delete it. So if you spent a bunch of time creating some really nice archive rules, you'll have to go back and recreate those. It's a trade-off, but if cost is something that's really important to you, then you should think about taking that approach as well. That brings us on to the last analyzer of the analyzer family that Jeremiah talked about here, which is the Internal Access Analyzer. This is one that I've pre-created for you, again, just because we wanted to get some findings that are generated.

Thumbnail 1950

Now what we've got on our list of S3 buckets over here, let me just filter these again as we've got a critical bucket. Jeremiah said Internal Access Analyzer is really aimed at those critical resources. It's a computationally intensive analyzer and it has a cost associated with it as well that you should definitely keep in mind. Not only that, it generates a lot of findings because it looks at each resource and tries to understand every access path that a principal can make to that given resource.

Thumbnail 1990

Thumbnail 2000

In my account it's not too bad, but in an account or maybe in an organization where I've got hundreds of thousands of accounts, there is a lot of information that is generated there. So if you're trying to find that needle in a haystack, it can be quite challenging. So keeping it to your most critical resources is super important. This one, for example, is probably my most critical S3 bucket where I've got some holiday photos of Jeremiah's here and I don't want people looking at these. I want to make sure I know who has access to those photos. I'm sure you'd agree with that.

Thumbnail 2020

Thumbnail 2030

So with our Internal Access Analyzer, as I've already created it, I'm just going to quickly show you the process so you understand what it looks like here. I'm going to call this JD's photos here, so I'm giving it a name. Again, make sure you make it nice and friendly. Then I can choose the resources that I want to add here. I can choose all resources from a given account, I can choose specific resources by specifying the Amazon Resource Name or the ARN for those resources, or I can choose or upload a CSV that has a list of resources in there as well that will then get analyzed by the Internal Analyzer. Then I just go and hit create and hopefully my analyzer gets created.

Thumbnail 2050

Now if I go into here and look at my findings, even for this one single bucket, we can see already that there are a lot of findings in there that have been generated. You can imagine, en masse, this for lots of buckets and lots of accounts could become a lot harder for us to try and understand and troubleshoot and when we're looking for specific information in there. Jeremiah, maybe you could share with our wonderful audience a little bit more about how Internal Access Analyzer works.

Thumbnail 2070

So this one, it's kind of funny because the original External Access Analyzer we launched, I'll just say a long time ago because I don't want to get it wrong, many years ago. But the Internal one we just launched like six months ago, and so I'm sure some folks were like, what, why was it so different? Well, it turned out we had to actually make some new science. It was really hard, but what makes it so challenging is

Thumbnail 2110

that in order for us to know who inside has access, it's not sufficient to just look at the resource policy. We have to look at every identity policy. We also have to look at all the SCPs and RCPs—all the organization control policies and permission boundaries, and so on. It's just a tremendous amount of metadata that we have to pull in, combine together, and then run through a fairly sophisticated scenario analysis using automated reasoning. It just takes a lot of computation.

If you didn't know, it does cost $9 per resource per month, so that's why it's something that does require a bit of consideration. It's really designed for your most critical resources. Well, similar to what we got from the others, the findings that have been generated have a similar look and feel. One of the interesting things that you find when you enable this for your critical resources is that you actually see there's a role or an IAM user here—a test user with all of the access. I don't know what that is, and I'm pretty sure that person doesn't need to see Jeremiah's holiday photos.

Thumbnail 2200

Thumbnail 2210

Thumbnail 2220

If I can click on that and inspect a little bit more to see what's actually going on there, we've got this principal, this IAM user called test-user-with-all-the-access, and he's got access to all of these things here, but probably doesn't need to see those photos. Similar to how I went back into the IAM console earlier on and had a quick look to see if I could find a bit more about this individual, I can see here's the user. This user, by virtue of the fact that at some point in the past I happened to give this user S3 star access—which isn't good practice, but I did because I was probably trying to troubleshoot some issue or help someone move forward with a project—I've inadvertently granted them access to Jeremiah's critical holiday photos now, and that person probably doesn't need access to that.

Thumbnail 2250

Thumbnail 2260

I can go away and see that this user was created in October, hasn't logged into the console before, and I can look at the last accessed API actions as well. I'm fairly sure it's going to come with no access to Estuary whatsoever. So it becomes a potential attack path, a path for data exfiltration or access that I wasn't intending. I hadn't created it intentionally—it wasn't malicious or nefarious. It was just because I had created a role or user at one point and granted them S3 full access. Now the internal analyzer has helped me understand that there is a way that that particular account IAM user, if it fell into the wrong hands, would be able to access Jeremiah's holiday photos and who knows where they would end up.

Thumbnail 2290

Let me bring up my best practices here again. I think we've harped on this one a little bit more with the internal analyzer, but keep in mind this is for your most sensitive of resources. There is a lot of signal created. You need to determine what's noise and what's not. If you're analyzing an S3 bucket that is accessible from accounts and principals in a large organization, it can become quite overwhelming to really prioritize where you focus your attention when it comes to cleaning things up.

We can import lists of ARNs and use CSVs to help you automatically specify what you want to analyze. As we talked about, this looks pretty intensively at resource policies, principal policies, and all the different ways in which a particular resource can be accessed by all the potential principals that can access it. This is great if you need to do user access reviews. I work with financial services customers in Australia, and a big part of their internal control is user access review, which can be a very complicated, time-consuming manual process. If we can optimize that even just a little bit by providing this mathematically verifiable information to their auditors and their compliance teams, it takes a whole swath of work off of their plate, so it's super powerful from that perspective. But it's the cost-benefit trade-off that they need to think about there.

Thumbnail 2400

Building a Proactive Pipeline: Integrating Custom Policy Checks with CDK and Bedrock

We've talked about the analyzers, and these are all in the verify and refine stage. You might then be asking yourself, well, maybe I should be doing things that actually stop these misconfigurations from ever getting into the environment in the first place. Yeah, it's probably a really good idea. I'm glad I asked myself that question because we've built something to show you that kind of helps solve that problem a little bit.

What we've built is an example of a pipeline using AWS CodePipeline for the purposes of this demo today. This pipeline has been integrated with the Access Analyzer custom policy check capability that Jeremiah brought up on the screen earlier. We are defining an organizational security standard that says S3 buckets should only be accessible to this account, the account that you're deployed into. If the bucket policy defines any other access path for a principal that is outside of this account, then that's a finding that should block the progress of the pipeline, we should get some feedback on that, and the developer or engineer who was writing the policy should be able to go and fix that problem.

If everything works well, then we should be able to deploy the stack, and this is an infrastructure as code stack in CDK as you'll see in a moment. One of the bits of feedback that I've often heard from engineers building IAM policies for their applications is that they're not IAM experts. They're experts in their applications, they know what their apps are supposed to do, they know the permissions they need, or at least they know what they want the app to do, but they don't know exactly how to craft the very nuanced IAM policies that are often required to get the outcome they're looking for.

So if you're going to tell them something's wrong, tell them how to fix it as well. That's fair. However, it's not scalable for a security engineering team, of which there are many fewer than there are software engineers, to be able to work with every single engineer and help figure out how to solve their problems. What we've done in this scenario is we've actually plugged in Bedrock because Watson and AWS talked during re:Invent without a bit of generative AI in there as well. We're using Bedrock to take the results of the finding and take the policies that we've got and actually provide very prescriptive guidance and recommendations back to the developer in the form of an automatically generated GitHub issue that will get pushed into the project for the developer so they can then take those actions and go and remediate their policies.

Thumbnail 2550

Thumbnail 2580

So that's how it should work. Let's hop over to the code, and this is where we do actually do a little bit of coding. Here is my CDK project. At the moment it's set to this account, so it's going to automatically add the account ID of whichever account I deploy into to the bucket policy here. This is the account that I don't really want to have access, so I'm going to paste that into there. What I've also got as part of our pipeline is this reference policy. This is my organizational guardrail that says when you create an S3 bucket, I want to make sure that at a minimum this account, so this is my current account, is the only principal or principals within that account that can access my S3 bucket, and these are the only actions that it should have. S3 star against any other kind of S3 resource. So if a policy that I attempt to create through my CDK project is anything other than a subset of this policy here, I should get a blocking finding, and it will stop my infrastructure as code template from being deployed.

Thumbnail 2620

Thumbnail 2650

Thumbnail 2660

Thumbnail 2670

Let's hit save. Let's add in my file. Let's commit here. It's easier probably to type commit. Git commit minus M, adding cross account. Hit. And then I'm going to do git push. This is where it all could come crashing down. It didn't, it worked. Okay, cool, so we've git pushed. What we should see is if we go over to our pipeline. So our pipeline in CodePipeline is kicking into gear now. This might take a few minutes to run through. What it's doing is when it gets to this stage over here, I've got three different custom policy checks configured. One is check no new access, so this is looking at my policy. To determine whether or not I am making sure that the policy I'm attempting to create is a subset of that reference policy, and if it's not, it will block and I'll get a failure. Check access not granted. I may have, I haven't in this scenario just to keep things simple, but I may have defined a set of IAM actions that I do not want any policy to grant principal access to, and I could list them in there, so I could list maybe S3 delete bucket for example. I don't want anyone to do that, so I could add that as a list and it would check those policies and block if it found it.

You can also specify resources there. For example, I might take the ARN of Jeremiah's holiday photo bucket, add that to a list of resources, and say if any policy that is being created could potentially grant access to that bucket, block it. I want to go and remediate that. And then finally, we have the check no public access, which checks to make sure that the resources I'm creating do not grant public access to the thing that I'm trying to create.

Thumbnail 2770

Thumbnail 2780

Thumbnail 2800

If all that goes according to plan and works the way we expect it to, then this will just deploy. But because I added that cross-account ID in there, what I'm hoping will happen is that this will fail and we will then see a GitHub issue automatically generated that I can pass to my developer and troubleshoot. We've got two of these through now. I'm going to play some elevator music to make it a bit more engaging and interesting, and I thought I would bring up the logs so you can see there's a lot going on here. I'll give you another Easter egg towards the end of the session where you can learn more about this and what's actually going on here. But what we're essentially doing is synthesizing the CDK project and extracting all of the IAM resources out of it, so the principals and the policies. We're then passing that over to a custom Python script that we've created that will analyze the results that get returned by the custom policy checks and then hopefully we should get a failure.

Thumbnail 2810

Thumbnail 2820

Thumbnail 2830

So we're going to check access not granted and check no public access. So far, so good, which is what I expected. If I then hop over here and jump back in for a second, let's go down. It should be getting pretty close. There's a lot of noise in here. Cool, and it has actually finished. That's good. And it failed. So it failed, hopefully because we got an issue. Here's the GitHub repository, hopefully you can all see that. I'm just going to note that we have one issue listed there at the moment. If I hit refresh, that should turn to two issues, which it did. If I go into here now, here's the issue that just got created automatically in the pipeline. I'll zoom in there a little bit just to show you what this looks like.

This is all powered by Bedrock at the back end. We've essentially passed the reference policy, our superset of permissions, and the particular statement ID from the policy that Access Analyzer determined to violate what we're asking it for. Both of those have been passed over to Bedrock along with a fairly prescriptive prompt that guides it to what we want it to create. We're essentially building a dynamic prompt, giving it a structure, and then passing in elements to flesh it out and add more details into it. We've said give us some very prescriptive guidance on what exactly we need to do here.

So we can see it's given us the problematic statement. If you've ever run Access Analyzer custom policy checks before or against a policy, you may be of the opinion that the feedback you get isn't always very prescriptive. You will usually get the name of the policy that has violated the rules and the statement index ID from zero to whatever. If you love understanding IAM policies, then that'll be great, you can just dive in there and figure it out. But if you're normal and you don't, then it can be a bit tricky to figure that out.

Thumbnail 2960

So what we've done is we've found that for you. We've taken that information from the analyzer outputs and then extracted the policy statements ourselves. We've taken that particular problematic one out and passed that over to Bedrock as well. So it's given us this. It's outlined the reference policy and then it's also given us specific guidance here. It said right there, your problematic statement allows access to perform these things, but the reference policy is only configured to permit this particular account. So there's your problem. Here's what you need to go and do to fix that step by step. Go fix that, walk through that, and remediate that problem.

Thumbnail 2970

Thumbnail 3000

If I go back here now, I'm going to take what I'll do is go back into here and copy and paste these just to make it a bit easier. If I go back through here and get rid of that and paste that in there, that should work. I'm going to add git commits and git push. Hopefully the cycle will continue. We will get the pipeline kicking back into gear again in a second if I find the pipeline.

Thumbnail 3020

I've used a placeholder value there for the ID of this account. It will auto-populate with the account ending 447, and the analyzer check should pass. The template should get deployed, and we've really shortened the feedback cycle. If I was the engineer writing that policy trying to get my application out there, think about the time savings. The feedback cycle we've just significantly shortened because I don't know if you've ever been involved in that back-and-forth between the engineer and the security engineer. The security engineer has no context of what you're trying to do, and the engineer just knows they're trying to get their thing out there. It's backwards and forwards, backwards and forwards, and it can take days, sometimes weeks to really figure out, "Yeah, I'm intending to do this and here's the reasons why." Now we've been able to give almost instantaneous feedback to the engineer to help them move much more quickly through the process.

Ideally, the analysis we went through a little bit earlier on external, internal, and unused access are really there as additional compensating controls to try and capture anything else that happens to get through the gaps that we weren't expecting. Because we've implemented these preventative controls really far left in that deployment lifecycle, we make sure that none of these bad things actually get out there in the first place. I think that has worked as well as I thought it would and hoped, and we can probably flip back to the slides now.

Thumbnail 3100

Closing Remarks and Additional Resources

If you are interested in learning more about this, in particular these proactive preventive kinds of checks, there are two different things that you want to check out here with these two QR codes. I'll continue to wait for a second. Sorry, they're so big. A lesson learned from a session I did a while back is I put about five or six of these on one slide once before, and no cameras could focus on any of them. They were all over the place, so we went for big QR codes this time.

Thumbnail 3130

If you want to see a good example of this with an actual third-party integration, basically a more full walkthrough of what Mitch just showed using GitHub Actions, there are two sessions that were so popular that we even got a repeat for that. Mitch will be there, and I won't. We're going to go into a bit more detail of the actual flow and the construction of that dynamic prompt in this session. We're going to show you how we integrate it with GitHub Actions as well, so you can see a little bit more under the covers of how we got the AI-generated analysis and prescriptive guidance back to the engineer. If you're in the area on those days, please come along.

Thumbnail 3180

That is it for our content. Thank you all very much. We would be remiss if we didn't mention that feedback is a gift. So please, if you get a chance to fill out the survey, if you enjoyed the session, let us know. That would be greatly appreciated. A score of five is always a good place, and we're happy with that. So let us know, and we'd really appreciate that. Hopefully you've found this useful. We've got a few more minutes left, so we're happy to stick around. We can answer some questions either here or outside, whichever works for us. But thanks, and hope you enjoy the rest of the conference. Yes, thank you all very much.


; This article is entirely auto-generated using Amazon Bedrock.

Top comments (0)