WEBVTT

00:00.980 --> 00:02.160
I'm Nimrod.

00:02.160 --> 00:03.960
I'm a solution architect at BridgeCrew.

00:03.960 --> 00:13.960
And over the next 35 minutes or so, I'd love to walk you through how you can utilize open source to do least privilege using infrastructure as code.

00:13.960 --> 00:14.260
Sorry.

00:15.480 --> 00:17.460
So, a bit about me.

00:17.460 --> 00:19.300
I'm a solution architect at BridgeCrew.

00:19.300 --> 00:29.060
BridgeCrew is a cloud security company that helps identify misconfigurations in both real cloud environments and infrastructure as code frameworks, such as Terraform, CloudFormation, etc.

00:29.060 --> 00:32.200
And we're doing all of this using grid automation.

00:32.380 --> 00:43.940
As part of my role in BridgeCrew, I'm involved with a few open source projects around AWS and Terraform, and security, which I either co-maintain or contribute to continuously.

00:44.180 --> 00:51.300
And my newest open source tool is called AirIAM, which I hope at the end of this talk you'll also be a fan of.

00:52.220 --> 00:53.700
Let's dive in.

00:54.820 --> 00:57.320
So, just a quick overview.

00:57.320 --> 01:05.760
AWS AirIAM is a service by AWS that manages all the privileges in your AWS account, in every AWS account.

01:05.760 --> 01:19.540
That means it includes all the privileges both for things that you need, your employees, your servers, but also for things that run in the background, like AWS services and access across services.

01:20.700 --> 01:24.400
So, it starts out really cool, and it allows that for everything.

01:24.400 --> 01:30.720
But the problem is that it is hard because it includes a lot of specifics and details.

01:30.900 --> 01:40.800
You create a user for every employee, and maybe for integrations, and for your CICD pipeline, and your servers, and it just becomes way too hectic.

01:41.240 --> 01:45.940
So, let's try to break it down and see why it is that way.

01:46.660 --> 01:51.320
When I look at AIAM, I think of it more like a road system.

01:51.320 --> 02:00.820
So, we have our users and our servers, and we have the resources, our data, our buckets, our databases, and all of those are destinations.

02:01.500 --> 02:07.780
And IAM, or privileges that are described in IAM, are like the roads between those entities.

02:08.600 --> 02:11.800
So, usually when you start out, you don't need a road planner.

02:11.800 --> 02:16.920
You have maybe two or three employees, and you set up maybe a server.

02:16.920 --> 02:18.620
That server serves your app.

02:18.620 --> 02:20.480
It can be behind a load balancer.

02:20.820 --> 02:22.020
It's pretty simple stuff.

02:22.020 --> 02:27.200
You won't need more than maybe two or three roles and top four or five users.

02:27.200 --> 02:31.260
But we don't use the cloud for this simple infrastructure.

02:31.260 --> 02:36.920
We use the cloud because it allows us to grow and scale and use more and more services.

02:37.180 --> 02:41.780
And sooner rather than later, you'll find yourself stuck in this kind of situation.

02:41.780 --> 02:53.480
You'll be adding more services, RDS, ECS, CloudFormation, CloudFront, more and more services, and all of those require different roles and different users.

02:53.580 --> 02:56.940
Some of them are maybe even third-party tools.

02:56.940 --> 02:59.740
And you also have different access patterns.

02:59.740 --> 03:12.280
You can start out by everybody using their own IAM users and then switch out to maybe using SSO and identity providers, which mean you have roles and not set of credentials.

03:12.280 --> 03:21.700
And all of that leaves layer over layer of unused and unnecessary privileges, which can be used by bad actors.

03:22.280 --> 03:30.900
Now, as a security person, which is kind of what I do, when I see IAM, I have only one question I really want to answer.

03:30.900 --> 03:33.560
And that is, who has access to what?

03:34.400 --> 03:45.320
It should be pretty simple, but I will now show you why it isn't that simple, specifically in AWS IAM, but that happens also in GCP, Azure, and other cloud providers.

03:45.900 --> 03:49.040
So let's start out with a simple question.

03:49.080 --> 03:53.720
Who has admin access, which is full access, to my AWS account?

03:54.280 --> 04:04.540
When I asked this question in the beginning, naturally I went to the administrator access, which is a managed AWS policy, and I tried to understand who has access to that policy.

04:04.540 --> 04:06.580
Who has that policy attached?

04:06.720 --> 04:09.520
So you can see here, this is an example account.

04:09.520 --> 04:14.820
We have two roles, which have admin access to the account, and also a group.

04:15.000 --> 04:21.400
Now, the group in itself is not any user or role, but we would like to know who is part of that group.

04:21.400 --> 04:28.160
So I clicked on the group, and now I see the group has 11 users, all of them have admin access to the account.

04:28.880 --> 04:35.520
The problem with IAM in AWS is that this isn't a complete list of all the admins in the account.

04:36.260 --> 04:37.800
And the reason is simple.

04:37.960 --> 04:46.760
IAM allows you to create your own policy documents, which are simple JSONs, in which you describe what you allow and deny for each entity.

04:46.760 --> 04:49.440
It could be a role, it could be a user, it could be a group.

04:49.900 --> 04:58.520
So this is an example of an inline policy, which means it's a policy for one specific role, which allows all actions on all resources.

04:58.560 --> 05:01.140
Well, that's what I would call an admin.

05:01.260 --> 05:02.900
And this isn't listed anywhere.

05:02.900 --> 05:04.200
It won't show up anywhere.

05:04.200 --> 05:11.300
You'll have to go entity by entity, policy document by policy document to find these entities.

05:12.420 --> 05:16.380
So this example shows us two problems we have with IAM.

05:16.400 --> 05:18.760
One is that it is easily bypassed.

05:18.760 --> 05:25.440
You can just create your own policy, it won't be listed anywhere, no one will know, and you can give any permission you'd like.

05:25.720 --> 05:29.360
The second one is that IAM supports complex relationships.

05:29.360 --> 05:30.620
Let's say you have a user.

05:30.620 --> 05:34.840
You can attach a managed policy to it, or you can put an inline policy.

05:34.880 --> 05:38.380
But as we've just seen, you can also do that using a group, right?

05:38.380 --> 05:44.140
You can have the user be a part of a group, and that group will have the policies attached or put on.

05:44.440 --> 05:46.840
But that's not all that IAM supports.

05:46.840 --> 05:49.680
IAM supports assuming role as well.

05:49.740 --> 05:57.560
So that means a user can assume a role and get the policies that are set on that role, or assume through that role another role.

05:57.560 --> 06:07.180
And that's a long chain of privilege excavation that you won't be able to see using simple console and going through the entities in IAM.

06:08.040 --> 06:09.640
But that's not all.

06:09.640 --> 06:14.660
Let's take a look at another example and see two other things we can find in IAM.

06:14.820 --> 06:19.320
So this is a list of the 11 admins from the admin group we've seen before.

06:19.600 --> 06:24.980
If we look at them, we'll see that 10 of them have access keys which are older than 90 days.

06:25.440 --> 06:33.580
So best practice is to rotate your keys every 90 days since these are static credentials that if discovered, they can be used to abuse the account.

06:34.620 --> 06:40.720
We can also see that four of these users have passwords and no MFA set.

06:40.720 --> 06:44.420
Now you might notice that most of them do not have password access.

06:44.420 --> 06:47.980
That's because we've moved over to using SSO.

06:48.060 --> 06:54.040
And these four users unfortunately did not do what was required of them, or they've been handled since then.

06:54.040 --> 07:01.260
But they do pose brute force risk to the account just by having passwords with no MFA.

07:01.600 --> 07:08.580
And if that's not enough, we also see that two users have not been used for more than half a year, more than 200 days.

07:08.580 --> 07:18.220
There's really no reason to keep live access keys that have such a high level of access to the account without them being used at all.

07:18.400 --> 07:21.120
So this example shows us two things.

07:21.120 --> 07:24.280
One is that it's difficult to enforce patterns over time.

07:24.280 --> 07:36.080
You have to manually go through the user list and find the, I would say, the people who are out of line or the resources that are misconfigured.

07:36.080 --> 07:38.480
But it's also hard to trace and verify usage.

07:38.480 --> 07:46.880
It could be that a person was using this account a lot for a year and has since stopped, but we won't know it unless we check.

07:46.880 --> 07:51.540
And we have to check it per user, per role, per entity in IAM.

07:53.160 --> 08:03.460
So we have all of these problems which cause layer and layer of garbage and stuff that's left behind and waiting to be now used.

08:03.480 --> 08:06.160
And we were wondering how we can do it.

08:06.160 --> 08:09.940
So what I developed is called Air IAM.

08:09.940 --> 08:11.300
It's completely open source.

08:11.300 --> 08:12.600
You can check out the link.

08:12.600 --> 08:14.780
I'll share it later too.

08:14.780 --> 08:18.140
And what it does is distribute IAM through Terraform.

08:18.140 --> 08:21.960
It creates Terraform code from your existing IAM.

08:21.960 --> 08:24.960
Let's walk through and see what it does.

08:25.560 --> 08:34.040
So before we created the open source, obviously, we had to do a few manual iterations to see what works and what doesn't.

08:34.040 --> 08:40.160
And we came to this flow of conclusions and actions.

08:40.260 --> 08:51.640
So at first we would like to collect all the IAM entities from the account and their usage using AWS APIs, maybe CloudTrail data and so forth.

08:51.700 --> 08:59.080
And then for each entity cross-reference it with its usage and decide whether the entity is in use or not.

08:59.080 --> 09:05.080
Whether the entity is in use or not is a question that depends on the threshold for usage.

09:05.080 --> 09:08.580
I would say the default best practice is 90 days.

09:08.580 --> 09:12.320
I've seen it go down to 30 or up to 365 days.

09:12.320 --> 09:14.380
So it really depends on your preference.

09:14.660 --> 09:17.120
Once we've decided what's not used, it's easy.

09:17.120 --> 09:18.500
We can mark it for division.

09:18.560 --> 09:22.340
And we will need to go through the permissions that are in use.

09:22.780 --> 09:40.540
So we will have to go through the entities and look at their permissions, look at what they've actually used using Access Analyzer or CloudTrail and create, I would say, a minimized version of the policies that they have based only on stuff that they use,

09:40.540 --> 09:46.940
meaning we won't be able to impair any workloads, not dev, not production, not anything.

09:46.940 --> 09:49.820
If it is in use, we're leaving it as is.

09:49.960 --> 09:53.120
The third one is to create a recommendation.

09:53.220 --> 10:05.660
That usually included a very large workbook with a few sheets in it that describes what we want to do for each entity with a few different, I would say, categories.

10:05.920 --> 10:17.500
And after we've done that, we'll take that to the relevant account stakeholder or the person who actually uses the account and knows the types of usage in the account.

10:17.500 --> 10:22.760
For approval, that might seem like a pretty long process.

10:22.760 --> 10:25.880
You actually won't understand how long it is.

10:25.880 --> 10:29.340
I've added some time estimations to the different steps.

10:29.340 --> 10:36.500
I would say the most difficult part is to create a recommendation and then get the approval from the relevant stakeholders.

10:36.640 --> 10:46.180
I've seen it take weeks and it's just a lot of misunderstanding and meetings and getting formal approval.

10:46.240 --> 10:53.240
And then I found out that even implementing the changes after I have the action items and I have the approval, it takes me a while.

10:53.240 --> 10:56.480
An hour is for a medium-sized account.

10:56.480 --> 10:58.780
It could take a lot longer for bigger accounts.

11:00.260 --> 11:11.960
So after iterating through this a few times and making sure that we understand what we need, we decided, like we do in many other fields here at Bridgecrew, that we want to automate it.

11:12.380 --> 11:23.100
When we wanted to build the automation, we decided that we have four main, I would say, goals we wanted to reach through the automation tool.

11:23.100 --> 11:28.440
So the first one is that we want to identify unused entities and easily remove them.

11:28.600 --> 11:32.380
When I say unused entities, I also mean unused policy attachments.

11:32.380 --> 11:39.100
So that means policies that are not in use at all by the role or user or group that has that policy attached.

11:39.100 --> 11:41.060
I want to also remove that.

11:41.500 --> 11:44.620
We want to be able to detect drifts and enable rollback.

11:44.620 --> 11:47.840
Let's say I made some modification and it caused downtime.

11:47.840 --> 11:50.260
For some reason, something went wrong.

11:50.260 --> 11:54.380
I can always roll back and make sure everything works.

11:54.960 --> 11:58.680
I want to be able to handle scales of thousands of entities.

11:58.680 --> 12:04.700
Again, when I say entities, also the relationships between the users and the policies and the roles and the groups.

12:04.700 --> 12:09.220
So it very easily reaches the 1,000, 2,000 threshold on big accounts.

12:09.640 --> 12:18.080
And then the fourth one, which is very important, is to be able to take the plan to get approval from the relevant stakeholders.

12:18.080 --> 12:24.260
But I want something that I can share and people will easily understand and either say that's fine or not.

12:25.640 --> 12:29.160
So the tool itself, ARIAM, is pretty easy.

12:29.160 --> 12:49.560
All it does is collect data from AWS APIs, both IAM and Access Advisor, cross-references it and either outputs it as CLI output for your convenience or Terraform code, which we'll see in a bit how that, I would say, leverages the power to the maximum.

12:50.840 --> 12:53.600
So let's start talking about the tool.

12:54.560 --> 12:57.600
ARIAM contains three commands built in.

12:57.600 --> 13:00.060
The first one is called Find Unused.

13:00.060 --> 13:07.000
What it does is collect all of the data from the APIs and decides whether the entity is used or not.

13:07.000 --> 13:09.960
The default setting is 90 days.

13:09.980 --> 13:12.520
Let's do a short demo and see how it works.

13:13.620 --> 13:14.660
Great.

13:14.980 --> 13:20.760
So I've already installed ARIAM on this computer, although it is very easy to install.

13:20.760 --> 13:24.780
And I can just run ARIAM Find Unused.

13:26.080 --> 13:29.660
So it now gets all the IAM configurations for the account.

13:29.660 --> 13:33.580
It will then collect the usage for all the users and the roles in the account.

13:33.580 --> 13:38.140
And right after that, it will output all the findings.

13:38.580 --> 13:39.400
Awesome.

13:39.400 --> 13:47.900
So you can see it's generating the reports, editing it, and now it will start outputting the unused entities that it found in the account.

13:48.000 --> 13:52.120
So as you can see, we have here four users who have not been used.

13:52.120 --> 13:54.920
It says last used 365 days ago.

13:54.920 --> 13:59.400
That's the maximum that AWS promises that there was no usage in.

14:00.280 --> 14:04.420
We can also see there's one active access key that isn't being used.

14:04.580 --> 14:09.260
You'll notice that it's for a user that's not listed under the unused users.

14:09.480 --> 14:12.620
So ARIAM does not give you duplicate results.

14:12.620 --> 14:19.280
If the user is unused, it won't say that its access keys are unused, although he might have access keys that are unused.

14:20.180 --> 14:21.180
Sorry.

14:21.400 --> 14:30.420
We also have one user, that's my user, which has password access to the console with MFA, but hasn't used it for over 100 days.

14:31.100 --> 14:33.720
If it doesn't have MFA, it will say it here.

14:33.720 --> 14:38.340
So you'll be able to understand who is, I would say, the bigger problem.

14:38.660 --> 14:42.000
We also have four roles which are unused.

14:42.000 --> 14:46.460
Those are roles that haven't been used for, I'd say, over 100 days.

14:46.460 --> 14:47.260
Yes.

14:47.360 --> 14:49.640
We have two groups which are redundant.

14:49.800 --> 14:57.480
One of them has no members, which means it's just laying there and it's a security hazard because, let's say, it does have any policies attached.

14:57.480 --> 15:02.400
If you attach a user to it, it will automatically gain all those permissions.

15:02.560 --> 15:08.320
So even it's just leaving behind privileges that maybe an attacker can utilize.

15:08.420 --> 15:10.540
And then group without policies.

15:10.540 --> 15:13.400
Groups can have members but have no policies attached.

15:13.400 --> 15:22.700
And since a group is not an entity that can be used in AWS, just groups' privileges, there's no point in having those groups.

15:23.200 --> 15:30.600
And since we want to make AWS IAM as manageable as possible, it also recommends deleting those kinds of groups.

15:31.000 --> 15:36.420
We have a redundant policy that's a policy that's not attached to any user, group, or role.

15:36.420 --> 15:40.340
It's just clutter that's being left behind in the account.

15:40.340 --> 15:42.640
And we also have two policy attachments.

15:42.640 --> 15:46.800
For policies that are unused by the relevant principle.

15:46.800 --> 15:53.540
So this user, S3User1, is not using any privileges given to him by Amazon API Gateway Administrator.

15:53.540 --> 16:03.500
But he does have that privilege given to him, which can cause him to make actions which he shouldn't, such as creating or even deleting existing API gateways.

16:04.680 --> 16:05.880
Great.

16:07.020 --> 16:10.720
So I hope we've got all of that clear.

16:10.720 --> 16:19.400
And this helps us actually create some of the permissions baseline, since it allows us to remove attachments of policies that are unused but given.

16:19.400 --> 16:23.520
And create more of a list privilege model for our IAM.

16:23.620 --> 16:26.360
The second command is called recommend groups.

16:26.360 --> 16:41.680
What it does is try to look through the users that you have in the account, group them according to their relevant privileges, and actually create recommendations for three types of groups currently.

16:41.680 --> 16:44.760
One is the admins group, which are active admins.

16:44.760 --> 16:51.000
The second one is power users, which are for users who have write access to the account but not admin access.

16:51.160 --> 16:53.460
And the third one is the read-only group.

16:53.460 --> 16:58.980
That's relevant for all the users who have read access to the account but don't have any write access.

17:00.200 --> 17:11.240
This command helps us finalize the permissions baseline or the changes we want to... the things that are in use and create the recommendation, what we want the account to look like in the end.

17:12.000 --> 17:14.440
So let's see that as well.

17:15.800 --> 17:21.710
I'll hit ARIM, recommend groups.

17:23.420 --> 17:24.540
Awesome.

17:24.540 --> 17:27.940
So in this account, we have two active users.

17:27.940 --> 17:31.700
One is my user, which is an admin and requires admin access.

17:31.700 --> 17:36.400
And also this S3 user one, which has write access to S3.

17:36.400 --> 17:40.920
We don't have any read users in this account, so it doesn't offer me the read-only.

17:40.920 --> 17:46.480
There's no point in creating empty groups as we've talked before, but if there were any, it would show them here.

17:48.800 --> 17:52.140
So we have the recommendation, it's just not actionable yet.

17:52.140 --> 17:58.320
We have everything we want to do, but we can't show it to anyone and we can't just hit play and make that work.

17:58.580 --> 18:00.840
That's where the third command comes in.

18:00.840 --> 18:02.440
It's called ARIM Terraform.

18:02.440 --> 18:05.540
And what it does is create Terraform code and state file.

18:05.760 --> 18:13.140
I'll show you how it works and we'll talk a bit about Terraform so you understand all the power that this command brings with this.

18:14.160 --> 18:28.280
So, I'll type in ARIM Terraform and what it does is it will initialize Terraform, it will create Terraform files for me, and then it will import the existing Terraform entities into the local state file.

18:28.280 --> 18:29.800
Let's see how that looks.

18:30.120 --> 18:36.840
So I'll change to the results there and you'll see that it created just now.

18:36.840 --> 18:38.720
This is in my time zone.

18:38.960 --> 18:45.820
It created the .terraform directory, which includes all the files that are necessary by Terraform to run.

18:45.820 --> 18:48.560
This is a temporary file, so you can ignore it.

18:48.560 --> 18:56.440
It creates .tf files that define all the different entities and their relationships using Terraform HCL code.

18:56.440 --> 19:05.600
It also creates a state file and the backup, which again, you don't need to care about because it is only temporary and for system usage.

19:05.600 --> 19:08.340
Let's take a look at groups.tf.

19:09.080 --> 19:18.140
So, what this shows you is the four groups that we have in the account and the policies that they have attached, if any.

19:18.140 --> 19:23.720
So, for example, we have the admins group and the admins group has administrator access attached to it.

19:23.720 --> 19:30.560
We have a group without members and that group has two policies attached, the RDS full access and the user change password.

19:30.560 --> 19:39.140
We also have a group without policies, which has no policies attached, and the S3 group, which has the Amazon S3 full access.

19:39.700 --> 19:48.340
Just so we can see it for real, I've opened the console for it and this is the groups in the account.

19:48.340 --> 19:59.420
You'll see these are exactly the four groups we have and you can see that the group without policies actually does not have policies and the group without members has these two permissions.

20:01.460 --> 20:04.460
So, the same goes for roles.

20:04.460 --> 20:07.260
Let's see the roles file, for example.

20:07.420 --> 20:10.840
So, for every role, we'll have the role itself.

20:10.840 --> 20:19.380
We'll also have the assume role policy document and if it has any policy attachments, such as this one, it will be listed as well.

20:19.380 --> 20:24.820
You'll notice that the syntax is not using any hard-coded strings.

20:24.820 --> 20:31.900
Basically, ARN creates the entities and connects them so you can actually see who has access to what.

20:32.840 --> 20:33.960
Awesome.

20:34.120 --> 20:35.580
So, that's all the code.

20:35.580 --> 20:37.420
Let's take a look at the state file.

20:37.960 --> 20:51.400
So, the way Terraform works is it creates both the code and the state file and the state file describes what connects the entities that were defined in code with the actual ARNs in the cloud environment.

20:51.420 --> 21:00.900
So, for example, we have here the AWS IAM group admins as we've seen it in the code and that's connected to this instance with this ARN.

21:01.160 --> 21:06.200
So, if I copy it and I go to admins, that's exactly the ARN of the group.

21:06.240 --> 21:24.060
So, that means this code describes this group and when I will run Terraform apply or Terraform destroy or Terraform plan, it will go and check what's configured in the code and what's configured in the state file and fix the differences.

21:24.060 --> 21:34.780
So, if it needs to delete or create or modify anything that's been described in the code and is not as is in the console, in the actual account, it will be fixed.

21:36.640 --> 21:37.680
Awesome.

21:38.080 --> 21:48.120
So, once I've created this, I can actually create the Terraform code, if you'd like, without the import stage which takes a while.

21:49.840 --> 22:00.340
So, this is what it does and if I type ls-la, you'll see that everything has updated except, well, it just finished now.

22:00.380 --> 22:04.900
So, if I run it again, you'll see that everything will change except the state file.

22:04.960 --> 22:05.980
See that?

22:06.020 --> 22:06.640
Awesome.

22:06.640 --> 22:10.540
So, the state file did not change, but all the tf files got updated.

22:11.580 --> 22:24.340
So, if I go into the results and type Terraform plan, you'll see that all the differences that it wants to do is unrelated to actual entity modifications.

22:24.400 --> 22:29.620
This Terraform code describes the actual entities almost one-to-one.

22:29.620 --> 22:33.220
You see it has a force destroy flag added to the users.

22:33.220 --> 22:42.800
That's so when you select to destroy a user, it will actually go and destroy, including the access keys, the password access, everything.

22:43.160 --> 22:48.600
So, I'll run Terraform apply just to make sure we don't have any differences.

22:48.600 --> 22:50.860
You'll see it takes a few seconds.

22:51.660 --> 22:58.360
And then we have the Terraform output form and the actual account exactly in line.

22:58.360 --> 22:59.340
Hold on.

22:59.340 --> 23:00.840
I don't want to break it.

23:00.840 --> 23:01.700
Yes.

23:02.460 --> 23:03.540
Awesome.

23:03.540 --> 23:08.200
So, now let's say I want to delete all the unused entities that I've just found.

23:08.400 --> 23:20.180
Instead of going through and deleting one-by-one the policies and the groups and the users and the roles, I can just type here minus minus without unused.

23:23.830 --> 23:24.470
Great.

23:24.470 --> 23:26.610
So, now it created the Terraform files.

23:26.610 --> 23:37.010
But if we'll take a look, for example, at groups.tf, you'll see that we only have two groups now, which are the two groups that both have users and have policies attached.

23:37.770 --> 23:39.450
Pretty simple.

23:39.650 --> 23:47.730
Now, when I run Terraform plan again, you'll see that it offers to delete everything for me.

23:47.730 --> 23:52.350
And it will be much higher than five or ten entities.

23:52.350 --> 24:01.190
It actually plans to destroy 40 through users, roles, policies, and all the relationships between them .

24:01.190 --> 24:04.830
And it will take just a few seconds and the Terraform will apply.

24:04.830 --> 24:06.510
That's all you need.

24:07.050 --> 24:08.150
Pretty slick.

24:10.150 --> 24:11.350
Awesome.

24:12.910 --> 24:17.430
So, we've created a recommendation that's very actionable.

24:17.430 --> 24:19.570
I can take it and apply it.

24:19.570 --> 24:23.650
But I don't have any way to show it and get approval for it.

24:23.710 --> 24:28.310
But another very powerful plus side of using Terraform is that it's code.

24:28.310 --> 24:31.910
And for code, we have version control systems.

24:31.910 --> 24:34.930
I like GitHub, so these are print screens from GitHub.

24:35.190 --> 24:49.730
But basically, what you can do is commit the Terraform code that is outputted by default with everything to a master branch, check out a new branch, run it without unused, for example, and open a PR.

24:49.730 --> 25:05.130
And that PR talks in a very simple language that developers can understand, even less technical guys can understand that if there's a group here that's called group without members and has a minus in front of it, it will probably get deleted.

25:05.310 --> 25:18.910
So you can use that to actually have all the conversation around getting approval and making everything, I would say, approved or agreed upon.

25:18.950 --> 25:23.730
And then, again, just a simple Terraform apply will make all those changes for you.

25:25.190 --> 25:27.250
So that completes our entire flow.

25:27.870 --> 25:39.330
Although we have three commands to help crunch through all the data and understand the phases, in general, you can just run directly RIM Terraform, it will do all the work for you.

25:39.330 --> 25:52.830
It will find all the unused entities, it will import them into Terraform, and you'll be able to actually run it again without unused or with unused, run Terraform apply, everything will be in your hands.

25:54.210 --> 25:56.550
Now, you've run it once, that's great.

25:56.550 --> 26:00.790
You have your IAM set up clean and sparkling and beautiful.

26:00.970 --> 26:12.010
But the problem with the cloud is that well, it's both a plus and a minus, I would say, is that people can manually change and make modifications.

26:12.730 --> 26:22.930
Now, using RIM on a weekly basis, monthly basis, on a regular basis, you'll be able to scan your IAM and identify drifts in existing configurations.

26:22.930 --> 26:36.370
That means if there were any modifications or deletions, you'll be able to find those things in code and actually automatically update your Terraform state and your Terraform code.

26:36.370 --> 26:39.770
You'll also be able to identify changes in usage status.

26:39.770 --> 26:43.650
So we've seen the problem where we had admins who have been unused for a long time.

26:43.650 --> 26:56.110
If you scan on a regular basis, it will by itself find entities that have been unused for 90 days or if you modify your threshold by your threshold and mark them for deletion and recommend you delete them.

26:56.570 --> 26:59.210
It will also help you identify new configurations.

26:59.210 --> 27:09.250
So let's say you have a new team or you have a new service or you even started a new Lambda and you created a role for it, that role will automatically be integrated into your Terraform.

27:09.250 --> 27:19.290
It will be imported into your state file and you can add it to your repository where you will still have it managed and you'll be able to see it.

27:19.330 --> 27:22.650
And nothing will go without knowledge.

27:23.430 --> 27:31.930
And then the last thing that ARAM and Terraform enable to you is to use static analysis tools to identify bad practices.

27:32.210 --> 27:50.030
So I would like to take this to the next slide actually which shows, I would say, two really great tools that will help you use infrastructure as code and static analysis for your permissions in your IAM.

27:50.150 --> 27:52.010
So the first one is called Chekhov.

27:52.010 --> 27:56.390
It's also pretty easy to install and I already have it set up here.

27:56.890 --> 28:01.490
So Chekhov, what it does is identify bad practices in Terraform.

28:01.710 --> 28:03.690
So if I run... let's see...

28:04.530 --> 28:07.130
the last thing I did was without the unused right?

28:07.130 --> 28:10.650
So I want to do it one second with everything.

28:10.950 --> 28:14.790
So right now I created Terraform for the existing IAM setup.

28:14.950 --> 28:20.230
And if I go to the results tab, I can just run Chekhov minus the results.

28:20.270 --> 28:25.590
This will make Chekhov scan all the Terraform files that are in the results directory.

28:25.850 --> 28:30.530
And we'll see in a few seconds that it has quite a lot of findings.

28:30.730 --> 28:34.310
So if I scroll up, yes, quite a lot indeed.

28:34.310 --> 28:39.690
So it found, it ran 56 checks and 23 of them failed.

28:39.690 --> 28:51.150
This includes misconfigured admins and bad assumer role policies and policies that are attached directly to users as this would require justification.

28:51.150 --> 28:53.950
Otherwise, it is really recommended to use groups.

28:54.450 --> 29:00.030
Let's say I ran it without the unused, just for checking what that would mean.

29:00.030 --> 29:06.810
By deleting all the unused entities and running Chekhov again, I will see how much cleaner the account is.

29:06.810 --> 29:08.130
And the account is a lot cleaner.

29:08.130 --> 29:14.190
So we only have two failed checks and both of them can be either justified or fixed.

29:14.450 --> 29:19.130
And all in all, we only have 11 checks that were scanned.

29:19.130 --> 29:24.690
That means a lot of the overhead was cleaned simply by deleting unused stuff.

29:26.130 --> 29:27.330
Awesome.

29:28.290 --> 29:31.410
Another really cool tool is PolicySentry.

29:31.410 --> 29:40.770
PolicySentry allows you to build IAM policies from scratch using YAML syntax and easy, simple CRUD syntax.

29:40.770 --> 29:48.070
So you have create, read and update and delete syntax for different resources and different services.

29:48.070 --> 29:55.250
And that creates an IAM policy that's probably better than what your average developer would create.

29:56.190 --> 30:03.330
If you're talking about scanning your existing configurations, I also have a few tools up my sleeve.

30:03.330 --> 30:11.550
So the first one, I would say the category is finer and more granular disk privilege for IAM.

30:11.550 --> 30:16.410
We have CloudTracker by Geolabs and Ardvark plus RepoKid by Netflix.

30:16.630 --> 30:33.510
They both use CloudTrail data, so you need to have CloudTrail read access to analyze the policies and mark specific privileges and break down all the stars and the jokers in your policy to understand what you're giving that isn't really in use.

30:33.510 --> 30:38.230
I would say that CloudTrail visibility or coverage is not 100%.

30:38.230 --> 30:43.130
Not all actions are by default recorded in CloudTrail.

30:43.130 --> 30:47.310
And so using CloudTrail comes with a...

30:47.310 --> 30:51.370
maybe you should take it suspiciously.

30:51.730 --> 30:55.750
Another really cool tool that I'd like to show is called CloudSplaining.

30:55.750 --> 31:01.530
CloudSplaining is another tool by Salesforce that identifies possible risks in your IAM configurations.

31:01.530 --> 31:07.650
So it has four different classes, privilege escalation, data exfiltration, other stuff.

31:07.650 --> 31:09.950
Let me show you real quick.

31:10.270 --> 31:12.410
So I run CloudSplaining.

31:12.410 --> 31:15.410
It's a very simple setup again.

31:15.750 --> 31:27.090
So what it does is it scans all of the policies that are in the account and it outputs a very detailed and rich report about all of the stuff that you can find in your account.

31:27.090 --> 31:38.850
You can actually go by the policies or by the principles, which is what I prefer, and just take a look, for example, who has access to infrastructure modification.

31:38.990 --> 31:47.290
So say the misconfigured admin user has... well, since he's a misconfigured admin user, he has all the bad stuff that he can.

31:47.290 --> 31:57.330
If we'll take a look at the misconfigured IAM user, you'll see that he has this very bad policy, which we've talked about.

31:57.330 --> 31:59.530
It allows everything on everything.

32:00.430 --> 32:09.410
So it shows that he can do a lot of infrastructure modifications, do privilege escalation, do resource exposure, and data exfiltration.

32:10.030 --> 32:16.290
You can actually go through this by risk and start diving deeper into that.

32:18.410 --> 32:23.930
And then the final tool I'd like to show you is called PrincipleMapper or PMapper.

32:23.930 --> 32:25.450
It's by NCC Group.

32:25.450 --> 32:29.570
It helps identify possible privilege escalations in the account.

32:29.570 --> 32:40.130
So if you remember, we had the graph where a user can assume a role and that role can assume another role and each role has its own privilege, I would say policy context of policies.

32:40.690 --> 32:42.750
So this tool creates a graph.

32:42.850 --> 32:44.370
You see it here.

32:44.470 --> 32:47.570
An example, it's a very partial graph.

32:47.570 --> 32:52.650
It has these two roles and this user, for example, can assume this role.

32:52.810 --> 33:02.050
And so the user, which is called EC2 Manager, can assume the role and gain all the privileges that are attached to EC2 role for SSM.

33:02.170 --> 33:13.430
And this allows you to map all the different roles and maybe if you identify a role that is super powerful, check who can assume it and make sure that that's in check.

33:15.830 --> 33:19.390
Yep, that's it for the slideshow.

33:20.650 --> 33:21.970
All right.

33:22.790 --> 33:37.890
I guess to start off with one question for me, I'm assuming that if you wanted to make a change, a specific change instead of the whole IAM recommendation made by AIR IAM, you would just go ahead and edit the Terraform file, right?

33:37.890 --> 33:48.150
And so are there any specific config files within AIR IAM that you can use to specify what to detect and what to ignore or anything like that?

33:48.150 --> 33:58.050
So Terraform itself allows you to maybe, I would say, create or modify or destroy anything you'd like within the code and the state file.

33:58.050 --> 34:00.490
So AIR IAM gives you all of the changes you'd like.

34:00.490 --> 34:12.530
You can run Terraform apply as I did in the slideshow, but you can also specify a specific target, be it a user, a group, or a policy, and Terraform will modify only that part of the findings.

34:12.970 --> 34:13.990
Got it.

34:14.070 --> 34:23.490
And then another one, do you plan on bringing any of these features to GCP or Azure, something along those lines?

34:23.670 --> 34:24.350
Definitely.

34:24.350 --> 34:27.810
So that's something that we've heard before.

34:27.810 --> 34:30.390
We are planning to do this.

34:30.390 --> 34:43.770
It requires a complete different set of, I would say, you need to use the other SDKs and it will require more knowledge because GCP IAM is not exactly like AWS IAM.

34:43.770 --> 34:52.270
It has a lot more of privileges given by the resources and not the principles, but we are definitely planning to go in that direction.

34:52.270 --> 34:53.230
Got it.

34:53.990 --> 34:56.830
Another question from Artemis in chat.

34:56.830 --> 35:00.750
How well do these tools work in a multi-account environment?

35:01.050 --> 35:02.850
That's a great question.

35:02.850 --> 35:08.810
So I would start out by saying that IAM permissions are limited to the account.

35:08.830 --> 35:16.110
You can give cross-account permissions, but that would be from one account you give the other account permissions.

35:16.170 --> 35:22.190
So the context of every, I would say, analysis is a specific AWS account.

35:22.190 --> 35:26.790
So you can use ARAM using all the default AWS credentials tools.

35:26.790 --> 35:30.470
You can use the profile and specify the minus minus profile flag.

35:30.470 --> 35:39.830
You can use AWS environment variables to scan different accounts, but every ARAM scan is limited to the context of one account since that is the context of IAM.

