start	end	text
0	6740	Hello, everybody. It's great to be here at Cloud Village. And in the next 30 minutes or so,
6740	10740	we're going to talk about static analysis of infrastructure as code.
11300	18320	Just as a side note, if you're interested in contributing to any of those open source
18320	26080	projects around AWS security, IAM security, infrastructure as code, or Google Cloud,
26080	32220	feel free to reach out. It's Barak Shoster at Twitter, or just follow my activity at GitHub.
32220	37420	I really like to work on open source projects, and it is one of the things that is great about
37420	43280	BridgeCode that is contributing more and more open source security tooling back to the community.
44860	51100	All right. So on the agenda today, we're going to talk about the state of open source
51100	57840	Terraform modules. Are they secured or not? We'll go over how to run Chekhov
58460	63220	using two different integrations, pre-commit hook and CI deployment.
64540	71320	And at the end of this talk, you should be able to just download Chekhov and run it on your own
71320	79760	manifests. Before diving into deployment, let's talk about the problem space. As engineers,
79760	89800	like myself, and probably you who are listening, our goal is to move faster and in much agile way.
91340	98600	And when we develop a new product, we need some way to deploy the infrastructure that
98600	106420	this product runs on. Infrastructure as code came to the world to help us just
106420	113520	do all this manual work at the cloud providers like the AWS, Azure, GCP consoles of setting up
113820	123640	a VM automatically and having this job of setting those instances reproducible, version controlled,
124160	130280	and peer reviewed. Since for the first time, it's in code, you can peer review it as a pull request
130280	138240	or merge request in your VCS. When you are working fast, you're producing probably more code,
138240	144280	and with more code comes more bugs. So in a lot of times, when you want to just provision
144920	151200	a new cloud resource, let's take S3, for example, you might miss some of the default configurations
151200	157640	and keep the S3 unencrypted by default or without versioning or without access logs.
157640	163220	And the same goes for other resources like compute resources. You might forget access
163220	170080	keys in your plain text environment variables instead of using a secured store. And when
170080	177720	you're copying pre-made templates from the internet that are unvetted, those issues might repeat
177720	184620	more and more. So Gartner said, and this is often quoted, that 95 of the cloud security issues
184620	193040	are related to configurations errors. And the trend that is being done at the past two or three
193040	198640	years, I know that Terraform exists for a little more than seven years, is that we're codifying
198640	205530	each and every activity that we're doing in YAML files, HCL files, etc.
208570	215770	These tooling, those manifests that we write, the infrastructure as code, are about provisioning
215770	222070	new resources in a reproducible way and about managing them. But it lacks the security
222070	227030	functionality or best practices vetting functionality. And there are some great
227030	235070	tools around this area. There is OPA, the open policy agent of the CNCF, and also Chekhov,
235070	240910	TFSEC, CFNAG. Each of those is tackling the problem from a different angle.
241590	247470	So let's talk about the problem that we're trying to solve using Chekhov, which is open source and
247470	256130	under Apache 2 license. What we try to understand is the default configuration of any kind
256890	262630	of infrastructure as code manifest, meaning Kubernetes, Terraform, CloudFormation,
262630	273010	serverless framework, etc. is secured by default. So we asked ourselves that question.
273010	281870	Let's scan as first open source modules of those cloud manifests.
282010	288990	So we decided to use Chekhov to scan thousands of open source repositories.
289770	295010	Before diving into the results, there are some interesting stats about the trend of
295010	300930	contributing and creating new infrastructure modules. And this is focused only on Terraform
300930	312650	modules. So back in 2017, 18, and 19, we had a mild growth in the amount of new open source modules
312650	320570	contributed around Terraform. And specifically at the COVID era, around February,
320570	327090	probably due to work from home productivity benefits, the contributions of new modules
327090	333530	went sky high, which is great. We'll have open source, more code that someone else is writing,
333530	339250	is less code for me to write. But the thing is, the more code that is being contributed,
339250	349110	the more misconfigs that are being found in the open source repositories. So 48% of those modules
349110	359970	have some kind of misconfiguration. So if we take about 2,500 modules, we'll see a lot of
359970	367010	misconfigs there. And those open source modules, by GitHub statistics, had more than 26 million
367010	374390	downloads. And that's a lot of downloads of misconfigured EC2 instances, S3 buckets, etc.
374850	380490	So just to make things clear, writing code in Terraform does not mean that it's insecure.
380490	386030	It's the other way around. Terraform gives the ability to peer review the infrastructure's code
386030	390570	and to have an impact on the configuration before provisioning.
391330	397830	The thing is, is that this practice of reviewing this infrastructure configuration
398650	405070	is still not in place in a lot of organizations. And what we see is that backup and recovery
405070	411110	is very often missed. Logging and auditing, encryption, Kubernetes configuration,
411850	416810	are also missed. You can understand Kubernetes that has so many knobs and switches,
416810	424090	but encryption should really be turned on by default on most of the cloud services.
424830	433510	And if we break it down to the different cloud vendors, we can see that there is a different
434330	441390	missing piece on all of those open source modules. For example, in Google, there is often
441390	451810	misconfigured networking piece, while on AWS, Kubernetes is the most often misconfigured code.
452070	458430	So where do those bad configurations come from, usually? So you can copy them from a blog post,
458430	464330	from Terraform registry, from GitHub, from your internal repository where you probably have a
464330	473570	platform team creating those manifests. And it's really not, usually it's not as a result of a
473570	481250	bad actor, but merely lack of knowledge or lack of time of all of those best practices. You have
481250	488950	over 160 services only on AWS, and the list of their configurations grows on and on.
488950	497070	So it's really a lot to miss, and a lot to be familiar with as a DevOps SRE or platform engineer.
497590	504850	And here comes Checkout. So Checkout was released on December 2019. It already has
505670	513630	more than 1,000 GitHub stars, 600,000 downloads, tons of best opinionated best practices
513630	521130	that comes within it. So more than 400 checks that are opinionated, are based on the CIS
521130	530090	benchmark, SOC2, PCI, and other best practices. And it has a bunch of CICD integrations.
532510	540070	So what Checkout is doing is giving you a policy as code. It gives you the ability to define a
540070	547750	best practice, and to version the best practice itself. Where this policy, for example, makes
547750	552790	sure everything is encrypted by default, can be peer-reviewed, can be automated as part of this
552790	558330	software development lifecycle. And specifically in Checkout, we decided that policies should be
558330	565990	written in a familiar language like Python. So let's take this example. We have here a
565990	574430	block that defines a database. And what is missing here is that storage is not encrypted by default
574430	580790	on the specific database configuration. How would a Checkout policy look like?
580790	587930	Well, when creating a custom policy, you can give it a name, an identifier, the type of resource that
587930	593290	you would like to inspect, which is AWS DB instance, a category, which is encryption.
593290	602130	And the scan itself is just, let's look for storage encrypted and make sure that it equals true.
602350	609230	If it does, let's pass it. Otherwise, let's fail the check. And Checkout is doing all of the wrapping
609230	617090	of making a very clear reporting option, a very clear CI integration. And we'll take a look on
617090	625110	how does that look like on CLI. So what I'm going to do now is I'm going to demonstrate Checkout
625110	633190	on a vulnerable by design project called TerraGoat. And if we will have time, we'll do the same for
633190	645060	Kubernetes Goat and CloudFormation Goat. So let's spin up the demo. All right. So what I have here
646020	655240	is just a very simple terminal. I'm using Mac. Before this talk, I've executed brew install
655240	663960	Checkout or pip install Checkout. Both would work for you. And what I have here are those three
663960	671520	projects of vulnerable by design infrastructure. But even on regular open source module, you will
671520	680460	likely find a misconfig. So let's dive into TerraGoat and take a look on the project structure.
680460	688800	So I have a Terraform directory that has resources among the three cloud providers.
688800	700760	Specifically on AWS, I have a Terraform file for S3 buckets. So over here I have a bucket
700760	708300	that is public, not encrypted, without access log and without versioning. And I have another file
708300	718880	for EC2 instances that has plain text access keys. But if I wouldn't tell you that,
718880	728460	it would have taken you a lot of time to see that. So let's run Checkout and see what it can do.
729240	736640	So the basic parameter is minus D. Choosing a directory that Checkout will scan the
736640	743480	infrastructure's code for. So what I'm going to do is I'm going to scan the AWS directory
745020	752280	and see how the results look like. So it should take a few seconds. And what Checkout found here
752280	761580	is 58 passing checks, meaning 58 times that cloud resources were with best practices on.
761580	770080	And 53 failchecks. So over here I can see all of those passing use cases. So I have here a database
770080	776200	application that is not open on RDP port, which is good. I've done some good work. But if I want to
776200	783280	on the bad things that it has found. So over here I have a bucket that is not encrypted at rest.
783280	792400	And this is why we have a failed check. And the resource is defined between line 1 and 13. And
792400	797880	I can see it here. And I can see that there is no encryption block. I've also written it to myself
797880	806180	as a comment. And if I'll take a look on the next set of resources that are right after S3,
806820	811980	here I have an unencrypted RDS. And that is publicly accessible.
813620	821560	And also plain text access keys found in this EC2 block. Here they are.
822680	829280	Why is plain text access keys bad? Because they're often used for crypto mining attack.
829280	835340	People can take those access keys and deploy a crypto miner. And basically my AWS bill will go
835340	843020	up and up and up. All right. So we have installed check off using pip install.
843020	849120	We've executed it on our local director of AWS. And we found a bunch of issues that we should solve.
850460	857960	But that was like a one time execution. How do I make sure that check off will run on each and
857960	863540	every change that I'm doing to my infrastructure as code? And I want check off to tell me, hey,
863540	871080	you have this specific issue. You should solve it before committing it to your GitHub account.
871300	878700	And from there to the production. So what check off has is actually a pre-commit integration
879540	886560	where you can do exactly that. You can configure a pre-commit hook. And on that scenario,
886560	895680	before each commit, check off will scan your local directory, your local repository,
895680	901900	and will prevent you from committing that bad code into your GitHub if it does not
901900	907620	follow those best practices. So let's take a look on how does that look like.
909780	919880	So if I go up here, and what I have configured is a pre-commit config YAML.
920240	928320	Mentioning that I should run the latest version of check off always on every commit. So
928320	938200	what I've done before this talk is I've created a new Terraform file called S3 new.
938540	948640	And it's not committed. Let's try to commit it. So what the pre-commit hook is doing right now
949220	958360	is running check off upon commit. And it fails my commit. I cannot push new code to my source
958360	969140	control unless it fixes those issues that are found in my S3 new Terraform file. Which is cool.
969140	976580	Now I don't need to run check off manually on each and every change. I can just install the
976580	987800	pre-commit hook. And now my workstation cannot upload bad S3 buckets. All right. So we have that.
987800	996800	The misconfig is gone. And I cannot use my workstation to write bad Terraform code.
996820	1001660	But what about workstations that did not deploy a pre-commit hook?
1003500	1009840	The best way to handle that use case is to install check off also in your CI CD pipeline.
1010480	1018260	Where on each change request, pull request, check off will execute as part of your CI.
1018940	1023980	And we'll call that check off job, for example, infrastructure security tests.
1023980	1029240	And it works just like any unit test. Where you're running application tests,
1029240	1033680	you can do the same with those 400 best practices of check off.
1034880	1044680	If check off approves or if the test passes successfully, you can deploy your infrastructure
1044680	1050940	code to production. If check off fails, on the other hand, it will block your pull request from
1050940	1059420	being merged. Just like unit tests that are blocked from being merged. So to do that specific
1059420	1069340	piece, we have developed actually a community contributed piece is a check off action.
1069560	1083330	Let's take a look on how it looks like. So if you go to BridgeCrew.io check off action,
1083330	1090630	you can see a project that is contributed by this handsome fellow called Chris Mavarkis.
1091350	1099250	And to configure a check off action in your GitHub action is as simple as that. You just
1100870	1108570	reference this specific action on your GitHub. And you can choose which checks to run, whether
1108570	1114070	to run them all, skip a specific one, scan a specific directory, or use any of the other
1114070	1122730	flags that check off has. And if you actually do that and enhance that into your CI pipeline,
1122730	1130150	assuming it's on GitHub action, it will look like this. So over here I have a pull request
1131050	1136270	on a repository that demonstrates a GitHub action of check off.
1137150	1146230	So here I have created a bunch of resources to create a new web server in Terraform.
1146230	1153970	So I have this AWS instance and the GitHub action have added annotations to my code
1153970	1162270	saying, hey, your AWS instance has hardcoded access keys and it's using unencrypted EBS.
1162270	1166350	And I should really solve those issues here in that code block.
1166430	1174230	And I also have issues with my security group, which has port 22 open to the entire internet.
1174570	1180750	And I should really solve that too. So check off will do a set of annotations for each and
1180750	1196330	every resource that is violating those best practices. So I have this pretty CI pipeline
1197050	1204290	that will check each and every commit. Not only if I'm doing that on my endpoint,
1204290	1208810	but also if I'm doing that directly on GitHub or from an endpoint that does not have pre-commit
1208810	1222290	hook deployed on. So what if I want to see the same being done for Kubernetes?
1223130	1229690	So there is actually a very cool additional project, very similar to Terracode,
1229690	1238130	that is about Kubernetes configuration. So it is a project created by Madhu
1239670	1245310	and it's called Kubernetes code. It has some amazing scenarios of
1246270	1254030	bad configured Kubernetes deployment manifests. And it has also a great Katakoda work through
1254030	1259410	that I really recommend doing just to get familiar with what are the best practices
1259410	1264470	and bad practices when configuring a Kubernetes cluster or a job.
1264490	1277480	What I have here on my local endpoint is actually this project already cloned.
1278120	1284680	And what I'm going to do is I'm going to run chkov-d kubernetes-code.
1290070	1296790	I'm going to run chkov-d on the scenarios directory. And I've actually created my
1296790	1303330	own scenario just before this talk. And I'm going to see what the results look like.
1303330	1310550	So chkov will now do the same that it has done for Terraform, but now for Kubernetes manifests.
1310930	1319090	So we have here a bunch of issues on my deployment channel. I like a lot of them.
1319150	1325710	I have here service account tokens that are mounted not when necessary.
1326250	1339230	I have UID conflicts. I have usage of root on my containers. And I should really solve
1339230	1346210	all of those deployments configurations across my pods. The one thing that is nice,
1346210	1351490	if you're not familiar with that specific configuration and what's the rationale behind
1351490	1359830	it and how to solve it, you can always go to those documentation pages that we have publicly
1359830	1367210	made accessible explaining what's the rationale behind this specific check and how to automate
1367210	1373230	the remediation of that specific configuration. So let's say that you're encountering a specific
1373230	1379810	config and you don't realize why you need to solve it. Here's the explanation where you have
1379810	1387750	the step-by-step guidelines to fix that. And obviously if you want to try to fix that
1387750	1392530	automatically, you can try the platform, but you can also use only the open source tools.
1393450	1402150	As for the last piece, there is actually a very cool way to use checkup for reporting mechanism,
1402150	1410630	just like reporting over passing and failing unit tests. Checkout has a reach output format
1411590	1418450	that has JUnit XML. And if you integrate that into a CI system like AWS CodeBuild,
1418450	1424210	you can actually get a very nice report showing the amount of passing and failing. And in some
1424210	1431390	systems like Jenkins, also to show the trend over time of those configurations.
1433550	1441170	Yeah, so I guess that's more or less about it on Checkov. Just to give some more references
1441170	1449450	of how to use it, you can always go into Checkov.io, start on the installation page
1449450	1456370	and getting started, which is the pip install piece. And right after you have those next
1456370	1466510	chapters that explains to you what are the existing resource scans. So Checkov has a list of
1468390	1477390	let's see 422 best practices that are opinionated that you can execute. But if you want to ignore
1477390	1485630	some of those and run only specific ones, you can always suppress tests that you won't like
1485630	1492090	to see. For example, if you have a public bucket and it should be public for website assets,
1492090	1498390	you can just use a very similar annotation to the one that you would use for JUnit
1499190	1506790	test, for example, or PyTest, which is Checkov skip, mentions the Check ID and a description
1506790	1515530	of why this resource should not adhere these best practices. So over here I have an S3 bucket
1515530	1523330	that should be public because it's serving as a static hosting for web content.
1524190	1528290	And you can do a very similar thing using a Kubernetes annotation
1530210	1535470	and mention why you want to skip a specific check and then Checkov will not fail
1535470	1543430	on that specific Check ID. There is some documentation also of how to integrate
1543430	1553010	Checkov with CI systems like GitHub Actions, Jenkins, GitLab CI, and also screenshots of how
1553010	1557610	that looks like on those specific environments.
1559000	1568170	All right, so if you have any questions, now would be a great time. I really encourage you to
1568680	1577090	try our open source tools, follow our blog where we update on those, and if you have any
1577090	1582990	questions on contributions that you'd like to make, feel free to reach out over email or Twitter.
1583650	1589990	I would be more than happy to do so. Just a quick question for me, what's next for Checkov?
1589990	1595010	Any other integrations that are in the works or any additional new features?
1595430	1604070	Right, so we had a bunch of requirements coming from the community. Some have asked for...
1604070	1609910	So the latest feature is actually ARM templates. We added ARM templates to Checkov so you can
1609910	1617430	use it not only for Terraform or CloudFormation Kubernetes, but also for this one.
1617550	1624330	And we also got requirements from the community for Ansible, and I think that's the big
1625030	1632350	next manifest probably. We don't have any resources scheduled yet to handle this one,
1632350	1640890	but any contribution would be accepted. And yeah, it already has most of the CI integrations
1640890	1647010	and Docker, a brew install, so it should be pretty straightforward to use.
1647390	1653870	Do you think if people used TerraGo modules more, this would help the number of misconfigurations
1653870	1658730	to go down? So TerraGrant is a do-not-repeat-yourself
1659450	1665090	framework for Terraform. It's a templating piece that helps to reduce the amount of code
1665090	1672430	that we're writing. So if you're writing less code, you probably create less misconfigs, but
1672430	1681650	if the templated configuration lacks the right defaults, so it will not reduce that specific
1681650	1687870	piece. So the answer is yes and no. Checkov specifically does not support TerraGrant.
1689210	1695570	Completely, but it does show value in some cases. So if you have a TerraGrant project,
1695570	1699370	I would be more than happy to see the results of Checkov on it.
1699370	1706110	We're researching how to make it work even better with templated modules.
