A secure software supply chain for OPA policies

Feb 22nd, 2023

Noa Shavit avatar

Noa Shavit

Security  |  

Open Policy Agent

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:

  1. 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.
  2. 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.
  3. Metadata. We need to be able to store signatures, as well as verify signatures. Fortunately, OCI allows us to do that.
  4. 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.

policy cli lets you tag, version, sign and test OPA policies

As always, we'd love to here your thoughts! Feel free to drop us a line, or join us on Slack.

Noa Shavit avatar

Noa Shavit

Head of Marketing