A secure software supply chain for OPA policies
Open Policy Agent (OPA) is gaining widespread acceptance as a mature decision engine. It is being used to enforce policies in a variety of domains, including Kubernetes admission control (Gatekeeper), configuration file policies (Conftest), and application / API authorization (Topaz).
Indeed, OPA policies are becoming an integral part of the cloud-native software supply chain. Security and operations teams have tools for packaging and signing application artifacts, and they need the same capabilities for OPA policies.
Tune into Aserto CEO, Omri Gazitt, as he describes how to build a secure software supply chain for OPA policies using open-source tools. Watch his Cloud Native SecurityCon lightning talk, or read all about it below:
Aserto is a developer platform for building fine-grained, policy based, real-time access control for cloud-native applications. It’s also the primary maintainer of Topaz, which is an open-source project for API and application authorization. Both of those systems are heavy users of the OPA project, so we care deeply about secure software supply chains for OPA policies.
Requirement for securing OPA policies
There are four requirements you need to meet to secure the software supply chain of OPA policies. These requirements, along with the open-source tools you can use to fulfill them, are listed below:
- A standard image format. OPA policies are built into tarballs by default, and tarballs don't lend themselves well to secure software supply chains. Fortunately, Open Container Initiative (OCI), a Linux Foundation project, can be used as an appropriate image format.
- A tool to build, tag, push and pull policies, just like Docker does for application images. The
policy CLI
, part of the Open Policy Containers (OPCR) project, is that tool. OPCR is a CNCF sandbox project that lets you build OPA policies into immutable images. These images can be tagged with a version, signed, pushed, and pulled. - Metadata. We need to be able to store signatures, as well as verify signatures. Fortunately, OCI allows us to do that.
- The ability to sign the policy. The
cosign CLI
, part of the OpenSSF Sigstore project, can be used to compute signatures over images and verify those signatures.
Let's see how these pieces fit together to transform OPA policies into immutable images that can be tagged, versioned, signed, and tested.
policy CLI - build, tag, push, and pull policy images
brew install opcr-io/tap/policy
echo $PAT | policy login -s ghcr.io -u <GitHub-account> --password-stdin
mkdir ./demo && cd ./demo
policy templates apply policy-template
tree .
policy build -t ghcr.io/<org>/policy-template:1.0.0 ./src
policy images
policy push ghcr.io/<org>/policy-template:1.0.0
policy CLI is a Docker-inspired workflow for OPA policies.
This gist uses policy CLI’s templating feature of to create a “hello world” Rego file. It then builds the policy into an OCI image. You provide it with a source code directory, image name, and tag, and it will build the image and store it as part of its local image registry.
policy CLI
also lets you list local images and push an image to OCI-compliant registries, such as GHCR, Docker, and AWS Container Registry. In this example, we're using GitHub’s container registry, GHCR.
Sigstore - sign and verify policy images
Next, we're going to sign the container images we just created. OPCR is going to use Cosign for that - it supports signing any OCI-compliant artifact.
brew install cosign
echo $PAT | docker login -u <GitHub-account> ghcr.io --password-stdin
cosign initialize
cosign generate-key-pair
cosign sign --key cosign.key ghcr.io/<org>/policy-template:1.0.0
cosign verify --key cosign.pub ghcr.io/<org>/policy-template:1.0.0
Here’s the gist.
OPA - run policy images
Finally, we need OPA to be able to obtain a policy from an OCI image. As part of the OPCR project we did some work upstream in OPA, enabling it to natively pull policy bundles from OCI artifact registries.
You need to tell OPA to use one of the container images. To do this, you need to modify the OPA configuration file: create a new service of type oci
and give it credentials. Then, in the bundles section, pass in the fully qualified container image name as a resource.
services:
ghcr-registry:
url: https://ghcr.io
type: oci
credentials:
bearer:
scheme: "Bearer"
token: "<PAT>"
bundles:
authz:
service: ghcr-registry
resource: ghcr.io/<org>/policy-template:1.0.0
opa run -s -c config.yaml
Alternatively, you can use Topaz to configure or pass the policy image as a container image.
topaz configure -d -r ghcr.io/aserto-policies/policy-todo:latest
Conclusion
OPA policies are important artifacts in the application lifecycle and need to be secured. You can do this by using the policy CLI
from the OPCR project to build, tag, push, and pull OPA policies as OCI images. And the cosign CLI
from the Sigstore project to sign and verify signatures over these images.
As always, we'd love to here your thoughts! Feel free to drop us a line, or join us on Slack.
Related Content
A CISO’s perspective on application security
There are many security considerations when developing an application. In this post, we share some considerations security teams have when evaluating application security. We also share a few best practices you can use to ensure your application is as secure as it needs to be now, and in the future.
May 10th, 2023
Assessing New Threats Related to Broken Access
Broken Access Controls are the most common reason for application security failures. They expand an organization’s attack surface and can allow the easy execution of novel attacks. Learn how to mitigate those attacks in this post.
Jun 28th, 2023
An “easy button” for API Authorization
Scaling a fine-grained authorization model for APIs can be tricky, especially when you have hundreds or thousands of them. Fortunately, Topaz makes it easy!
Jul 8th, 2024