Rego policies for Choria Server

Open Policy Agent is a CNCF incubating project that allow you to define Policy as code. It’s widely used in various projects like Istio, Kubernetes and more.

It allows you to express authorization policies - like our Action Policy - in a much more flexible way.

Building on the work that was done for aaasvc, I’ve added a rego engine to the choria server, which will allow us to do most of what actionpolicy allows, as well as:

  • Assertions based on the arguments sent to actions
  • Assertions based on other request fields like TTL and Collective
  • Assertions based on if the server is set to provisioning mode or not

Read below the fold for our initial foray into OPA policies and what might come next.

Lets look at an example OPA Policy as it relates to a specific user.

package io.choria.mcorpc.authpolicy

# it only checks `allow`, its good to default false
default allow = false

# User can deploy the "frontend" package, in collective "production"
allow {
	input.callerid = "choria=vjanelle.mcollective"
	input.action == "install"
	input.agent == "package"
	input.collective == "production" == "frontend"

# can ask status anywhere in any environment
allow {
	input.action == "status"
	input.agent == "package"

# user can do anything the agent package in development
allow {
	input.agent == "package"
	input.collective == "development"

The context this will run in is the choria server - meaning each individual node. Currently there is no bundle distribution mechanism(if you are familiar with OPA), so you will need to ensure that the rego policies are distributed to your nodes, much like the current actionpolicy. OPA itself ships with a number of built in functions to further enhance the capabilities of your policies. For example, you could limit actions to certain times of the day, or even issuing http requests to other services

Within the policy, the following fields are present as input:

  • agent - The Agent struct
  • action - A MCORPC Request
  • callerid - The CallerID value from the Request
  • collective - The Collective as defined in the Request
  • data - Request Data, if any - all inputs sent to the action
  • ttl - Time To Live, from the request
  • time - The time the request was made
  • facts - any facts present on the choria server
  • classes - any classes present on the choria server
  • agents - Additional agents present on the choria server
  • provision_mode - If the choria server is compiled with provisioning mode enabled, and configured

This capability has been released with in v0.13.1, however it is still experimental. There are additional capabilities of Open Policy Agent which we have not enabled as of this writing.

Additionally, if you’re using the puppet modules to deploy choria and mcollective, as of v0.10.3 you can specify rego_policy_source parameter to deploy a a managed policy file, on a per-agent basis. A default rego policy is included to ensure that default-deny semantics are shipped, for a secure by default posture.

To enable rego policy processing, you set the rpcauthprovider to rego_policy. During development of policies, you can either change the loglevel to debug, or set the plugin.regopolicy.tracing configuration value to true. This will provide enhanced information about policies and evaluations in the logs.

See also