Securing the software supply chain for Policy-as-Code
Jun 23rd, 2022
Since emerging as a graduated CNCF project last year, the Open Policy Agent (OPA) project has been adopted in a wide variety of scenarios: Kubernetes admission control (gatekeeper), policy enforcement over configuration files (conftest) and authorization for APIs and microservices.
In all of these instances, extracting policy out of an application and expressing it as code has substantial benefits. You can achieve a separation of concerns, where a security team can own and evolve the policy independently of the artifacts over which they are applied.
For example, a security team can create policies that enforce important engineering rules, such as only using approved golden images in Dockerfiles, ensuring that containers never run as a privileged user and requiring that all deployments go to a dedicated namespace with proper technical, business and security labels. Security teams can also create authorization rules that dictate which microservices can talk to each other, guaranteeing that production services never talk to staging or vice versa.
OPA policies are powerful, but the default packaging format (a tarball) is not. Tarballs don’t have many of the benefits we’ve come to expect from modern artifacts such as OCI containers:
- Facilities for adding metadata
- Using tags for semantic versioning
- Standard protocol for pushing and pulling tagged images from artifact repositories
But, perhaps most importantly, OCI images can be signed with Sigstore/cosign, ensuring a secure software supply chain.
What is Sigstore?
Sigstore is a free signing service for software developers that is seeing rapid adoption across the cloud-native landscape. For example, Kubernetes 1.24 will officially use Sigstore to sign all artifacts and allow developers to verify those signatures. Sigstore supports signing any OCI-compliant artifact.
Why sign your policy bundles?
Policies are made up of code that is no less important than any other code in your system—application code, infrastructure code and so on. As mentioned, policies often encode the business rules that an organization uses to maintain security and compliance. So, ensuring the integrity of policies is just as important as any other artifact in your system.
Building policies into OCI images
To use Sigstore, first you need to start building your policies into immutable OCI images. To do this, you’ll need to use the policy CLI from the Open Policy Registry (OPCR) project. The policy CLI is modeled after the Docker CLI—it provides commands for building, tagging, pushing and pulling OPA policies as OCI images.
Besides being a step toward a secure software supply chain for policies, packaging your policies as OCI images gives you all the other advantages associated with OCI—immutability, explicit versioning and a standard interchange format between dev, ops and secops.
The OPCR project provides actions for building, tagging, pushing and pulling policy images, to make it easy to integrate into the CI pipeline for policy artifacts.
Signing and verifying signatures
Once you’ve made the transition to OCI images, you can use cosign to sign the policy bundle in the same way you sign any other OCI image. Just as importantly, before you run a policy, you should verify its signature.
Running policy images
As of v0.40, OPA natively supports policy bundles packaged up as OCI images. This means that you can switch from tarballs to OCI images as the preferred packaging format for your OPA policies.
A secure software supply chain for policies
With policy, cosign and OPA all supporting an OCI-based workflow for policies, you can now achieve a standard, secure software supply chain for your policy artifacts.
To dive deeper, you can find a complete set of examples in the Open Policy Registry docs. Happy hacking!