Open Policy Agent examples

Modified on Mon, 22 May, 2023 at 11:25 PM

Direktiv supports Open Policy Agent (OPA) to provide permissions and context checks within the system. The following examples show a few use cases of how to use it.

Allow Changes Only During Business Hours

OPA checks every line in the permission check if it returns false. In this case we are checking if the hour of the day is greater than 22 and smaller than 6.

The checkError function is a Direktiv helper function which can be used to return the error message to the user interface. If it is not used the user gets a simple not authorized message.


checkBusinessHours = true {
   output := time.clock(time.now_ns())
   print("hour of the day:", output[0])
   checkError(output[0] > 22, "can only be changed after 22:00")
   checkError(output[0] < 6, "can only be changed before 6:00")
}

To apply it to one of the functions it can be added to the function which should be protected:


workflowStore {
   hasAccess
   checkBusinessHours
}

Allow Only Images With Tags

If there are no tags defined for an image Kubernetes pulls the latest images from the repository. This can lead to unexpected consequences because the flow could run with a new version of an action without knowing it. There for it is useful to check if a tag is defined. As a simple mechanism to test this is to check for an occurrence of a colon.


Functions can be used in two different locations in Direktiv. The first are the workflow-scoped images in the functions block:

functions:
- id: get2
  image: direktiv/request:v1
  type: knative-workflow

The function block is an array so it needs to be iterated and every single function needs to be checked. The following OPA snippet defines a checkTag function which accepts a parameter which is the full definition of a function.It returns true if it the type is knative-namespace or subflow. If it is knative-workflow it has an additional check for a colon in the image name. The OPA function checkFunctionTag is using an iterator using the OPA every keyword.


checkTag(fn) := true if {
   fn.type == "knative-workflow"
   print("checking function", fn.id, fn.image)
   checkError(contains(fn.image, ":"), "images requires tags. don't use latest.")
} else := true if {
   fn.type == "knative-namespace"
} else := true if {
   fn.type == "subflow"
}

checkFunctionTag {
   every fn in input.workflow.functions {
     checkTag(fn)
   }
}

This test function can be easily executed in the workflowStore function.

workflowStore {
   hasAccess
   checkFunctionTag
}

The above protects the workflow from using un-tagged images but to protect the whole system the namespace services needs to be checked as well.  The serviceManage OPA function is being called for creating and deleting of namespace services. 

Because the value service is only set on the creation path it can be checked if the value of service has been set. This value is undefined for the delete action. The following OPA code snippet returns true if service is undefined and true if service and the image contains a colon.


checkService(svc) := true if {
  svc.service
  checkError(contains(svc.service.image, ":"), "images requires tags. don't use latest.")
} else := true if {
  not svc.service
}

This function needs to be added to the servicesManage OPA function.

servicesManage {
   hasAccess
   checkService(input)
}


Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article