Providers
Providers are the policy engines which evaluate the input data from the specified domain. Currently supported Providers are:
- OPA (Open Policy Agent)
- Kyverno
The provider block of a Lula Validation
is given as follows, where the sample is indicating the OPA provider is in use:
# ... Rest of Lula Validation
provider:
type: opa # opa or kyverno accepted
opa-spec:
# ... Rest of opa-spec
# ... Rest of Lula Validation
Each domain specification retreives a specific dataset, and each will return that data to the selected Provider
in a domain-specific format. However, this data will always take the form of a JSON object when input to a Provider
. For that reason, it is important that Domain
and Provider
specifications are not built wholly independently in a given Validation.
1 -
Kyverno Provider
The Kyverno provider provides Lula with the capability to evaluate the domain
in against a Kyverno policy.
Payload Expectation
The validation performed should use the form of provider with the type
of kyverno
and using the kyverno-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: kyverno
kyverno-spec:
policy:
apiVersion: json.kyverno.io/v1alpha1 # Required
kind: ValidatingPolicy # Required
metadata:
name: pod-policy # Required
spec:
rules:
- name: no-latest # Required
# Match payloads corresponding to pods
match: # Optional
any: # Assertion Tree
- apiVersion: v1
kind: Pod
assert: # Required
all: # Assertion Tree
- message: Pod `{{ metadata.name }}` uses an image with tag `latest`
check:
~.podsvt:
spec:
# Iterate over pod containers
# Note the `~.` modifier, it means we want to iterate over array elements in descendants
~.containers:
image:
# Check that an image tag is present
(contains(@, ':')): true
# Check that the image tag is not `:latest`
(ends_with(@, ':latest')): false
You can have mutiple policies defined. Optionally, output.validation
can be specified in the kyverno-spec
to control which (Policy, Rule) pair control validation allowance/denial, which is in the structure of a comma separated list of rules: policy-name1.rule-name-1,policy-name-1.rule-name-2
. If you have a desired observation to include, output.observations
can be added to payload to observe violations by a certain (Policy, Rule) pair such as:
domain:
type: kubernetes
kubernetes-spec:
resources:
- name: podsvt
resource-rule:
group:
version: v1
resource: pods
namespaces: [validation-test]
provider:
type: kyverno
kyverno-spec:
policy:
apiVersion: json.kyverno.io/v1alpha1
kind: ValidatingPolicy
metadata:
name: labels
spec:
rules:
- name: foo-label-exists
assert:
all:
- check:
~.podsvt:
metadata:
labels:
foo: bar
output:
validation: labels.foo-label-exists
observations:
- labels.foo-label-exists
The validatation
and observations
fields must specify a (Policy, Rule) pair. These observations will be printed out in the remarks
section of relevant-evidence
in the assessment results.
2 -
OPA Provider
The OPA provider provides Lula with the capability to evaluate the domain
against a rego policy.
Payload Expectation
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.test
The 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.
Policy Creation
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.