Chainguard Enforce now has support for the Rego Policy Language. Rego is a declarative policy language that is used to evaluate structured input data such as Kubernetes manifests and JSON documents. This new feature of Enforce enables users to apply policies that can evaluate Kubernetes admission requests and object metadata to make comprehensive decisions about the workloads that are admitted to their clusters. Rego support also enables users to enhance existing cloud-native policies by adding additional software supply chain security checks all in one place: Chainguard Enforce.
This blog will help you start defining useful Rego-based policies and distributing them to your clusters in Enforce. For more information about writing Rego policies, check out the Rego Policy Language Docs.
A typical use case for Enforce is ensuring that container images are trusted before being admitted to a cluster. However, in many cases, organizations want to ensure not just the provenance of the container images themselves, but also that the runtime container instances meet a baseline threshold security posture.
For this tutorial, let’s imagine that an organization has the following two security policies:
The Enforce Policy Catalog contains several pre-written Rego-based policies that you can customize and apply to easily enforce security best practices on your clusters. The catalog also contains a blank Rego policy template that you can use to build your own policy, like this one.
We’ll use this template to construct our organization’s policies.
First, let’s look at the ClusterImagePolicy spec: which is defined in the sigstore API.
Now let’s build our policy:
Since we want to use Rego to evaluate structured data that isn’t supplied in the registry image itself, we need to provide some input data for the policy to use:
The API defines the following options:
Since we want to evaluate the metadata labels and Pod Security spec, we need to includeSpec: and includeObjectMeta:
The policy type: should be “rego” (By default, Enforce supports “cue” policy language here), and the policy itself is defined in the data: field.
Rego policies in Enforce must include package sigstore, and must evaluate the isCompliant boolean to “true” to successfully pass the policy. You can see that isCompliant is set to false by default, and the logic in the braces must flip the boolean to true for the policy to pass. This same structure must be present in all Rego-based policies in Enforce.
Additional details about this structure:
To access the data we’ve imported above, start your statements with “input.” and append the input document hierarchy down to the level of the value you want to evaluate. Let’s start by checking that the required labels exist in the ObjectMeta data:
This policy will evaluate to true only if both labels exist in the metadata portion of the manifest.
Now let’s check to make sure our Pod Security Specs are properly set:
This policy will pass if all the restricted values are set to false.
In some cases, you may want to evaluate an item that can be repeated in the manifest, such as an image source that is included in multiple container specs in the same manifest, such as this snippet with a disallowed nginx image from dockerhub:
In this case, you’ll need to iterate over the image array and check all the relevant fields for the restricted value. You can use [_] to iterate through the array. The Rego docs show that you can use not in conjunction with the contains() built-in function to evaluate all items in the array.
This policy will not admit pods that come from docker.io.
Finally, let's construct a policy that disallows privilege escalation in Pods per the Kubernetes PodSecurity Baseline standard:
This policy shows a method of declaring a variable and using it to count up all the instances of privilege escalation across Pod types, and evaluate that the final count is 0 to pass.
These are some very simple examples to help you get started writing Rego policies in Chainguard Enforce. The Rego Language Reference describes many more built-in functions, operations, and data types you can use to evaluate your policies, just remember that you must use the sigstore API standard isCompliant evaluation in your Enforce policies.
Sign up for a free trial of Chainguard Enforce to start securing your software supply chain today!