The notion of shifting security left — to an earlier point in development — has been common in the industry for many years. The idea has primarily found purchase in the world of application security. Until recent years, it has been difficult to implement left-shifted security in the world of infrastructure due to the lack of technologies or tools to enable this practice. In this Advisor, we review a real-world scenario that almost all security professionals have faced in their careers. Here, we focus on the code. In our next article, we will explore the architecture itself.
You have doubtlessly heard the many stories about companies that have had data stolen due to an S3 bucket misconfiguration. These misconfigurations usually result from two primary issues: encryption and public-facing access. In this scenario, when your company goes to move into the cloud, you would at the same time write a policy that prevents this level of access. So, now that we have a security policy written, how do we consistently enforce the rules?
Monitoring is easily available in the market with tools such as CloudGuard Dome9 or Prisma Cloud. An issue with this approach is twofold; with the sheer volume of S3 buckets that are typically created at an enterprise, enforcement would eat up many hours, with your security operations team constantly having to respond to these issues. Additionally, once a bucket is set public, the assets are grabbed almost immediately by the countless bad actors on the Internet who are constantly scanning for these types of misconfigurations in the hopes of hitting their big payday. How do you solve for this issue by shifting your security left to prevent these misconfigurations from occurring in the first place? Consider this overview of an example implementation of policy as code:
HashiCorp’s Terraform is an open source infrastructure-as-code software tool that provides a consistent command line interface (CLI) workflow to manage hundreds of on-premises or cloud services. Terraform Sentinel is an embedded policy-as-code framework integrated with various HashiCorp Enterprise products. It enables fine-grained, logic-based policy decisions and can be extended to use information from external sources. These two tools combined allow your security and technology teams to provision secure, purpose-built infrastructure that you can then use to guarantee compliance to your policies by implementing those policies as code.
Terraforming an S3 Bucket
Using a real-world example, let’s say that your company just hired a developer who is going to work on building a serverless application to process and store your customers’ data. It relies on a storage backend in S3. The developer is brand new, and the project managers are pushing for him to deliver value as quickly as possible. That typically doesn’t include time for him to read through, digest, and understand all of the security policies that you wrote. He would login to his development environment to get to work and provision an S3 bucket in the manner shown in Figure 1.
Great, he’s off to delivering value. But now you have an S3 bucket in your AWS account that is not encrypted and is also now public on the Internet. Worse, once the application is up and running in lambda, the developer is going to start sending customer information to this bucket.
Let’s quickly go over the appropriate configuration for a bucket that matches your security policy to understand what our desired state is.
The code block shown in Figure 2 changes your access control list for the bucket to be set as private and also applies a customer-owned KMS key to use to encrypt any object that goes into the bucket. Now our bucket is secure and matches the security policy! How would you go about enforcing this? Better yet, how do you enforce this and also let your developers know directly what your security policies are for the way they work with code?
Sentinel — Policy as Code
This is where the Sentinel policy comes in. You can let your developers know immediately as they are submitting their code that the configuration is against your company’s security policies and that their code will not build (see Figure 3).
The best part about this is that your security engineers do not need to be developers themselves to write these functions. As you can see in Figure 3, the code required to enforce your policies is pseudocode and human-readable. This idea of human readability is enforced by ensuring there are good code comments inserted directly in the code. In past engagements, we’ve also included the security policy name and control number to help make this enforcement mechanism more easily auditable.
If the resource the developer has created passes, then the developer will receive a message in the development console or CI/CD pipeline that states the code is compliant and meets all requirements. Otherwise, the developer will receive a message informing them which of their resources have failed and what security configuration is missing.
There are various mechanisms you would use to force this to run alongside your CI/CD pipelines. In this example, we have only covered the code itself. In the next article in this series, we will explore the entire architecture required.
“Sentinel Overview” (www.terraform.io/).