Wilson Mar bio photo

Wilson Mar


Email me Calendar Skype call

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Open Policy Agent runs queries in the Rego language

US (English)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Cyrillic Russian   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


What is OPA?

OPA (Open Policy Agent) is purpose-built for reasoning about information represented in structured documents.

OPA is about a 20MB binary designed to be run close to the software needing policy decisions, often as a Kubernetes sidecar.

OPA has 50+ built-in functions (strings, numbers, regexps, network CIDRs, JWTs, arrays, objects, sets, etc.).

VIDEO: Gatekeeper is the subproject that integrates OPA with Kubernetes admission control.

Gatekeeper’s competition is Kyverno, which better understands Kubernetes (such as parents of resources), resource generation, easier to use, and has better reports.

Open Policy Agent provides a unified policy language – Rego – that can be enforced across the cloud-native stack (Kubernetes, Kafka, Spinnaker CI/CD, Terraform, Kong, etc.)

Rego is also used within the Kubernetes Admission Controller to validate logic in deployment descriptors before applying them to a cluster. One example of this is creating a policy that only allows deployments that reference containers from trusted repositories.

Conftest is the name of the subproject that runs OPA policies against files on a file system.




BLOG: AWS Config custom rules are written in the Rego language processed by the general-purpose Open Policy Agent (OPA).

Lambda can use an OPA (Open Policy Agent) Engine to evaluate rules stored in S3.

https://github.com/aws-samples/aws-management-and-governance-samples.git (from AWS) is a collection of code samples for the Management and Governance services which includes: CloudWatch, CloudFormation, Cloudtrail, Config, Systems Manager, and more.

It contains cfn_templates (CloudFormation templates) to deploy Lambda function and AWS Config rules; lambda_sources source file for the Lambda function and the OPA binary that is a deployed as a layer for the Lambda function. Packaged sources are under the packaged_lambda_assets directory. opa_policies contains Rego policies that correspond to rules deployed by CloudFormation templates.

Rego language

Rego is described the native query language Rego for OPA processing nested documents.

Rego is declarative queries are assertions on data stored in OPA. So policy authors can focus on what queries should return rather than how queries should be executed. These queries are simpler and more concise than the equivalent in an imperative language.

The queries define policies that enumerate instances of data that violate the expected state of the system.

If all the statements in the body hold to be true, the return value is “ground” (i.e a constant).

STAR: Take the OPA Policy Authoring course by Tim Hinrichs (@tlhinrichs), CTO of Straya, OPA’s inventor.

  • https://medium.com/@mathurvarun98/how-to-write-great-rego-policies-dc6117679c9f
  • https://www.fugue.co/blog/5-tips-for-using-the-rego-language-for-open-policy-agent-opa

This sample Rego code from Docker Captain Viktor Farcic & Daring Pope in Spain, author of technologyconversations.com and books from DevopsToolkitSeries.com) gives an example:

  • In dev, no more than a 100 instances
  • Not allow “latest” tag in production


A sample OPA file opa/block-node-port.yaml:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockNodePort
  name: block-node-port
      - apiGroups: [""]
        kinds: ["Service"]

From among https://github.com/open-policy-agent/gatekeeper-library

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
  name: k8sblocknodeport
    description: Disallows all Services with type NodePort.
        kind: K8sBlockNodePort
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8sblocknodeport
        violation[{msg: msg}] {
          input.review.kind.kind == "Service"
          input.review.object.spec.type == "NodePort"
          msg := "User is not allowed to create service of type NodePort"

Let’s look at the app.yaml file containing “type: NodePort”:

apiVersion: v1
kind: service
  name: devops-toolkit
    app: devops-toolkit
  type: NodePort
  - port; 80
    targetPort: 80
    protocol: TCP
    name: http
    app: devops-toolkit

When the above is enabled and this command is issued to process a yaml containing NodePort:

kubectl apply --filename app/app.yaml

These (rather redundant) messages would appear:

deployment.apps/devops-toolkit created
ingress.networking.k8s.io/devops-toolkit created
Error from server ([denited by block-not-port]) User is not allowed to create service of type NodePort): error when creating "app/app.yaml": admission webhook "validating.gatekeeper.sh" denied the request: [denied by block-node-port] User is not allowed to create service of type NodPort

The fix would be to define the NodePort to a ClusterIP:

  type: ClusterIP

OPA install

curl -L -o opa https://openpolicyagent.org/downloads/v0.31.0/opa_linux_amd64_static