The OPA provider provides Lula with the capability to evaluate the domain against a rego policy.
The validation performed should use the form of provider with the type of opa and using the opa-spec, along with a valid domain.
Example:
domain:
type: kubernetes
kubernetes-spec:
resources:
- name: podsvt
resource-rule:
group:
version: v1
resource: pods
namespaces: [validation-test]
provider:
type: opa
opa-spec:
rego: | # Required - Rego policy used for data validation
package validate # Required - Package name
import future.keywords.every # Optional - Any imported keywords
validate { # Required - Rule Name for evaluation - "validate" is the only supported rule
every pod in input.podsvt {
podLabel == "bar"
}
}Optionally, an output can be specified in the opa-spec. Currently, the default validation allowance/denial is given by validate.validate, which is really of the structure <package-name>.<json-path-to-boolean-variable>. If you have a desired alternative validation boolean variable, as well as additional observations to include, an output can be added such as:
domain:
type: kubernetes
kubernetes-spec:
resource-rules:
- group:
version: v1
resource: pods
namespaces: [validation-test]
provider:
type: opa
opa-spec:
rego: |
package mypackage
result {
input.kind == "Pod"
podLabel := input.metadata.labels.foo
podLabel == "bar"
}
test := "my test string"
output:
validation: mypackage.result
observations:
- validate.testThe validatation field must specify a json path that resolves to a boolean value. The observations array currently only support variables that resolve as strings. These observations will be printed out in the remarks section of relevant-evidence in the assessment results.
The required structure for writing a validation in rego for Lula to validate is as follows:
rego: |
package validate
validate {
}This structure can be utilized to evaluate an expression directly:
rego: |
package validate
validate {
input.kind == "Pod"
podLabel := input.metadata.labels.foo
podLabel == "bar"
}The expression can also use multiple rule bodies as such:
rego: |
package validate
foolabel {
input.kind == "Pod"
podLabel := input.metadata.labels.foo
podLabel == "bar"
}
validate {
foolabel
}Important
package validate and validate are required package and rule for Lula use currently when an output.validation value has not been set.
Custom OPA modules can be imported and referenced in the main rego module. The following example shows how to import a custom module and use it in the main rego module:
Let's say we have a file that is called lula.rego with the following contents that verifies that pods have
the label lula: "true":
package lula.labels
import rego.v1
has_lula_label(pod) if {
pod.metadata.labels.lula == "true"
}We can import this module and use it in the main rego module as follows:
domain:
type: kubernetes
kubernetes-spec:
resources:
- name: podsvt
resource-rule:
group:
version: v1
resource: pods
namespaces: [validation-test]
provider:
type: opa
opa-spec:
modules:
lula.labels: lula.rego
rego: | # Required - Rego policy used for data validation
package validate # Required - Package name
import future.keywords.every # Optional - Any imported keywords
import data.lula.labels as lula_labels # Optional - Import the custom module
validate { # Required - Rule Name for evaluation - "validate" is the only supported rule
every pod in input.podsvt {
lula_labels.has_lula_label(pod) # Use the rules defined in the custom module
}
}Note
The validate.rego module name is reserved for the main rego policy and cannot be used as a custom module name.