Automated governance is an important topic that we discuss as part of software delivery. And for many organizations, it can be the driving factor for investing in CI/CD platforms. However, not every deployment has to be risky. One practice is to introduce policy as code which allows users to codify policy decisions in software. This is beneficial because policy as code decouples decision logic from business logic in services. And we can even go as far as to make policy decisions based on an application or environment’s context. This blog post will share why we care about policy as code and how it can apply to software delivery.
Why use policy as code?
Every business tests its products before releasing them to its consumers. Software services are no different, and every organization has its practices, tools, and processes that verify the health, readiness, performance, and accuracy of an application. These allow us to make guarantees to consumers and users of our product. This helps ensure that all changes are in compliance and adhere to a set of standards.
There are 2 ways to go about making a decision while testing a service. An individual or team can manually decide if a decision is correct or automate the decision-making process. One scales better than the other. Treating policy as code allows for automated decision-making, giving developers and engineers the independence to manage feature defining work without sacrificing compliance.
What is policy as Code?
Policy as code involves writing code in a high-level language to manage and automate policies. The high-level language is dependent on the policy engine, which takes a query input, some data, and policy to produce a query result. For a policy engine such as the open-source Open Policy Agent (OPA), the policies are expressed in a declarative language called Rego. Alternative policy engine solutions aside from OPA include Hashicorp’s Sentinel.
Let’s describe the three inputs needed to make a decision.
- Policy: The policy represents the coded logic that models the decision-making process.
- Data: The data is information from an application, environment, or service. This data is provided in a JSON format for OPA.
- Query Input: The query triggers the decision-making process based on the supplied data and policy provided uploaded to the policy engine. The policy engine service listens on a port for the JSON query made via an API call.
Here are links to resources to learn more about OPA and writing policies.
- Open Policy Agent Introduction @ CloudNativeCon EU 2018: video, slides
- Rego Deep Dive @ CloudNativeCon EU 2018: video, slides
- How Netflix Is Solving Authorization Across Their Cloud @ CloudNativeCon US 2017: video, slides.
Like any other piece of code it’s important to have the right processes in place to support development. OPA has a VSCode extension to support development within an IDE, alongside with a complete testing suite which allows you to unit test your policies.
What are some policy as code use cases?
Some common use cases which policies include:
- Authorization Control for application services: Implementing fine grained access control for an application is one of the most common use cases for policy as code. To check authorization a service makes an API call to the policy engine to output whether the request is authorized or not. (Here is some policy as code which you can use to implement API Authorization in OPA: https://github.com/open-policy-agent/opa#example-api-authorization)
- Infrastructure Provisioning within the cloud: Enforcing specific requirements on Public Cloud resources such as mandatory tags on instances, firewall and networking settings, and provisioned machine or instance types. (How to apply this use case using Hashicorp’s Policy Engine Sentinel: https://www.terraform.io/docs/cloud/sentinel/examples.html).
- For Kubernetes control: you can manage Kubernetes by writing policies against different kubernetes resources like pods, namespaces, and nodes. You can ensure container images come from trusted registries. I recommend looking at OPA Gatekeeper (and we describe in another Harness blog post how to deploy Gatekeeper as part of your continuous delivery process: https://harness.io/2020/04/open-policy-agent-primer/).
Creating checks is a major part of the software delivery process. The earlier and faster we can catch errors or noncompliance, the better the software delivery process. This blog post shares some interesting use cases that policy as code can help automate. If you’re interested in trying policy as code I recommend looking at Open Policy Agent. If you’d also like to try OPA with Harness as part of your CI/CD pipeline register for free at: harness.io