Rego Templates
Rego Policy is much more powerful than Config Poliy, but it's also more complex. To make it easier to write Rego Policy, we provide a few templates for common use cases.
Rego Policy Requirements
There are some special requirements on Rego policy used by Ratify. The package declaration MUST be package ratify.policy
, and there MUST be a boolean variable valid
declared. The variable valid
MUST be set to true
if the overall verification is successful, and false
otherwise. The input
is a Json object that contains the verification results of all reference artifacts.
Examples
Here is a sample of the input
:
{
"verifierReports": [
{
"artifactType": "org.example.sbom.v0",
"subject": "test.azurecr.io/test/hello-world:v1",
"referenceDigest": "test.azurecr.io/test/hello-world@sha256:22222",
"verifierReports": [
{
"verifierName": "sbom",
"verifierType": "sbom-verifier",
"isSuccess": false,
"message": "error msg",
"extensions": {}
},
{
"verifierName": "schemavalidator",
"verifierType": "verifier-schemavalidator",
"isSuccess": true,
"message": "",
"extensions": {}
}
],
"nestedReports": [
{
"artifactType": "application/vnd.cncf.notary.signature",
"subject": "test.azurecr.io/test/hello-world@sha256:123",
"referenceDigest": "test.azurecr.io/test/hello-world@sha256:33333",
"verifierReports": [
{
"verifierName": "notation",
"verifierType": "verifier-notation",
"isSuccess": true,
"message": "",
"extensions": {
"Issuer": "testIssuer",
"SN": "testSN"
}
}
],
"nestedReports": []
}
]
}
]
}
Example 1
Require all reference artifacts associated with subject image to be verify successfully. Check equivalent Config Policy
package ratify.policy
default valid := false
valid {
not failed_verify(input)
}
failed_verify(reports) {
[path, value] := walk(reports)
value == false
path[count(path) - 1] == "isSuccess"
}
failed_verify(reports) {
[path, value] := walk(reports)
path[count(path) - 1] == "verifierReports"
count(value) == 0
}
Example 2
Require at least one reference artifact of the same type to verify succesfully. (relaxes the default policy to 'any'). Check equivalent Config Policy
package ratify.policy
default valid := false
valid if {
not failed_verify(input)
}
failed_verify(reports) if {
newReports := {"nestedReports": reports.verifierReports}
has_subject_failed_verify(newReports)
}
has_subject_failed_verify(nestedReports) if {
[path, value] := walk(nestedReports)
not artifact_type_pass_verify(value)
path[count(path) - 1] == "nestedReports"
}
# at least one artifact of the same type passed verification
artifact_type_pass_verify(nestedReports) if {
count_artifact_type(nestedReports) == count_successful_artifact_type(nestedReports)
}
count_artifact_type(nestedReports) := number if {
artifact_types := {x |
some i
x := nestedReports[i].artifactType
}
number := count(artifact_types)
}
count_successful_artifact_type(nestedReports) := number if {
artifact_types := {x |
some i
x := nestedReports[i].artifactType
artifact_pass_verify(nestedReports[i].verifierReports)
}
number := count(artifact_types)
}
# an artifact has at least one successful report
artifact_pass_verify(verifierReports) if {
verifierReports[_].isSuccess == true
}
# should be at least one verifier report that is successful
failed_verify(reports) if {
[path, value] := walk(reports)
path[count(path) - 1] == "verifierReports"
count(value) == 0
}
Example 3
I trust multiple identities, and need to find at least one valid signature signed by any identity.
Prerequisites:
- The artifact is only signed by Notation, there might be a few signatures attached to the artifact.
- Users has configured different Notation verfiers, and each verifier has a different identity.
package ratify.policy
import future.keywords.in
default valid := false
valid {
not failed_verify(input)
}
# Fail the verification if no signatures are signed by trusted identity.
failed_verify(reports) {
not has_trusted_signature(reports.verifierReports)
}
# Fail the verification if no signatures are present.
failed_verify(reports) {
[path, value] := walk(reports)
path[count(path) - 1] == "verifierReports"
count(value) == 0
}
# There is a signature signed by trusted identity.
has_trusted_signature(reports) {
some report in reports
report.artifactType == "application/vnd.cncf.notary.signature"
pass_validation(report.verifierReports)
}
pass_validation(reports) {
some report in reports
report.isSuccess == true
}