Validating arbitrary data
In this tutorial we’ll introduce some basic Conforma concepts and look at examples where Conforma is used to apply policy checks against arbitrary input data.
We often use the ec validate image command, which fetches and
verifies an image’s SLSA provenance attestations, then applies policy checks
against them. But Conforma can work just as well with any kind of input using
the ec validate input command, and in fact that is a useful way to
demonstrate some Conforma ideas and techniques.
ec validate input
Conforma can perform policy checks on arbitrary data with ec validate input. Let’s try an example.
A simple data file:
# file: input.yaml
animals:
- name: Charlie
species: dog
- name: Luna
species: catA minimal Conforma policy defined in Rego:
# file: no-cats/main.rego
package main
# METADATA
# title: No cats
# description: Disallow felines.
# custom:
# short_name: no_cats
# solution: Ensure no cats are present in the animal list!
#
deny contains result if {
some animal in input.animals
animal.species == "cat"
result := {"code": "main.no_cats", "msg": "No cats allowed!"}
}To use that policy, Conforma needs a policy.yaml file specifying a source:
# file: policy.yaml
sources:
- policy:
- ./no-catsNow we can run Conforma like this:
$ ec validate input --file input.yaml --policy policy.yaml
Success: false
Result: FAILURE
Violations: 1, Warnings: 0, Successes: 0
Input File: input.yaml
Results:
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: No cats allowed!
Error: success criteria not metUsing –info for more detailed output
The metadata associated with the policy rule is important for
Conforma. Adding the --info flag will use the metadata to show more
details about the violation:
$ ec validate input --file input.yaml --policy policy.yaml --info
Success: false
Result: FAILURE
Violations: 1, Warnings: 0, Successes: 0
Input File: input.yaml
Results:
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: No cats allowed!
Title: No cats
Description: Disallow felines. To exclude this rule add "main.no_cats" to the `exclude` section of the policy configuration.
Solution: Ensure no cats are present in the animal list!
Error: success criteria not metUsing –show-successes to show passing checks
Let’s “fix” the violation and run it again:
$ sed -i "s/cat/rabbit/" input.yaml# file: input.yaml
animals:
- name: Charlie
species: dog
- name: Luna
species: rabbit$ ec validate input --file input.yaml --policy policy.yaml --info
Success: true
Result: SUCCESS
Violations: 0, Warnings: 0, Successes: 1
Input File: input.yamlBy default there’s not much output on success, but we can add
the --show-successes flag to change that:
$ ec validate input --file input.yaml --policy policy.yaml --info --show-successes
Success: true
Result: SUCCESS
Violations: 0, Warnings: 0, Successes: 1
Input File: input.yaml
Results:
✓ [Success] main.no_cats
FilePath: input.yaml
Title: No cats
Description: Disallow felines.(Turn rabbits back into cats for the next step):
$ sed -i "s/rabbit/cat/" input.yamlWarnings
We can use “warn” to produce a warning instead of a violation:
(We’ll append to the existing file here.)
# file: no-cats/main.rego
# from-line: 16
# METADATA
# title: Charlie warning
# description: Charlie is a troublemaker!
# custom:
# short_name: charlie_watch
# solution: Keep a close eye on Charlie.
#
warn contains result if {
some animal in input.animals
animal.name == "Charlie"
result := {"code": "main.charlie_watch", "msg": "Charlie is here"}
}Notice we now see the warning in the output:
$ ec validate input --file input.yaml --policy policy.yaml --info --show-successes
Success: false
Result: FAILURE
Violations: 1, Warnings: 1, Successes: 0
Input File: input.yaml
Results:
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: No cats allowed!
Title: No cats
Description: Disallow felines. To exclude this rule add "main.no_cats" to the `exclude` section of the policy configuration.
Solution: Ensure no cats are present in the animal list!
› [Warning] main.charlie_watch
FilePath: input.yaml
Reason: Charlie is here
Title: Charlie warning
Description: Charlie is a troublemaker!
Solution: Keep a close eye on Charlie.
Error: success criteria not metWarnings are considered non-blocking.
Adding more detail to the violation reason
Rego is an expressive and capable language so we can easily add more detail to the violation reason. For example:
# file: no-cats/main.rego
# from-line: 10
deny contains result if {
some animal in input.animals
animal.species == "cat"
result := {"code": "main.no_cats", "msg": sprintf("A cat named %s was found!", [animal.name])}
}$ ec validate input --file input.yaml --policy policy.yaml
Success: false
Result: FAILURE
Violations: 1, Warnings: 1, Successes: 0
Input File: input.yaml
Results:
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: A cat named Luna was found!
› [Warning] main.charlie_watch
FilePath: input.yaml
Reason: Charlie is here
Error: success criteria not metIf there are multiple cats, we now get multiple different violations:
# file: input.yaml
animals:
- name: Charlie
species: dog
- name: Luna
species: cat
- name: Fluffy
species: cat$ ec validate input --file input.yaml --policy policy.yaml
Success: false
Result: FAILURE
Violations: 2, Warnings: 1, Successes: 0
Input File: input.yaml
Results:
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: A cat named Fluffy was found!
✕ [Violation] main.no_cats
FilePath: input.yaml
Reason: A cat named Luna was found!
› [Warning] main.charlie_watch
FilePath: input.yaml
Reason: Charlie is here
Error: success criteria not metThat’s about it for this lesson. Hopefully you now have a better idea of what Conforma policies look like, and what kind of output Conforma produces.
Before we wrap this up let’s look at two extra tips which should be useful when integrating these kind of policy checks into a CI or build system:
Machine readable output
Text output is the default, but you can also output json or yaml, which includes some additional information not included in the text output:
$ ec validate input --file input.yaml --policy policy.yaml --info --output json | fold -s -w 400
Error: success criteria not met
{"success":false,"filepaths":[{"filepath":"input.yaml","violations":[{"msg":"A cat named Fluffy was found!","metadata":{"code":"main.no_cats","description":"Disallow felines. To exclude this rule add \"main.no_cats\" to the `exclude` section of the policy configuration.","solution":"Ensure no cats are present in the animal list!","title":"No cats"}},{"msg":"A cat named Luna was
found!","metadata":{"code":"main.no_cats","description":"Disallow felines. To exclude this rule add \"main.no_cats\" to the `exclude` section of the policy configuration.","solution":"Ensure no cats are present in the animal list!","title":"No cats"}}],"warnings":[{"msg":"Charlie is here","metadata":{"code":"main.charlie_watch","description":"Charlie is a troublemaker!","solution":"Keep a close
eye on Charlie.","title":"Charlie warning"}}],"successes":null,"success":false,"success-count":0}],"policy":{"sources":[{"policy":["./no-cats"]}]},"ec-version":"v0.8.97","effective-time":"2026-02-11T22:38:39.207175414Z"}“Strict” vs “non-strict”
By default we produce a non-zero exit code if there are any
violations, which is useful to interrupt a script or a CI task. You can change
that behavior if you need to with --strict=false:
$ ec validate input --file input.yaml --policy policy.yaml > output.txt; echo "Exit code: $?"; head -3 output.txt
Error: success criteria not met
Exit code: 1
Success: false
Result: FAILURE
Violations: 2, Warnings: 1, Successes: 0$ ec validate input --file input.yaml --policy policy.yaml --strict=false > output.txt; echo "Exit code: $?"; head -3 output.txt
Exit code: 0
Success: false
Result: FAILURE
Violations: 2, Warnings: 1, Successes: 0