Writing a rule
Rules in Rego
Rules are written in Rego. When you are writing Rego, you do two things:
Write rules that make policy decisions. A rule is a conditional assignment.
Organize rules into policies. A policy is a set of rules with a hierarchical name
To learn more about the Policy Language, visit the OPA Policy Language Documentation Page.
You can also use the OPA Playground to try out Rego or run examples of this guide.
How to generate a new rule
There are two options to get started:
Use the
template
command to generate the required files for writing a rule:This generates the scaffolding for the rule, including fixture files based on the provided configuration format. For more details, read the documentation about the template command.
Create a Rego policy from scratch and match the expected file and folder structure on your own:
rules
└── my_rule
├── main.rego
└── main_test.rego
You will have to write your own Rego testing framework if you do not use the template
command.
Structure of the rule
In Rego, you can write statements that allow or deny a request, such as:
allow { input.name == "alice" }
or deny { input.name == "alice" }
If the template
command was used to generate the rules, then the default entry point is rules/deny
. To override it and use a different name from deny
, refer to the section Bundling Rules.
This is what a generated skeleton of a deny rule looks like when you run snyk-iac-rules template --rule NEW-RULE --format hcl2
:
You must follow this format of the msg property to ensure the output is displayed correctly from the Snyk IaC CLI.
The attributes are:
publicId: a naming convention unique to your team, such as COMPANY-001. This should not contain/start with “SNYK-” to differentiate it from the internal Snyk rules.
title: a short title that should summarise the issue.
severity: this can be one of low/medium/high/critical.
msg: Snyk recommends changing only the resource name and property, for example,
input.aws_s3_bucket[%s].tags
to match your example. The functionsprintf
is provided by Rego and enables Snyk to provide a dynamic error message explaining exactly where the issue was found.
The following attributes are optional but can be used to enhance the scan results in the Snyk CLI:
issue: a more detailed string explanation of what the exact issue is.
impact: a more detailed string explanation of what the impact of not resolving this issue is.
remediation: a more detailed string explanation of how to resolve the issue. Snyk recommends providing a code snippet here.
references: you can provide an array of strings with URLs to documentation
The generated test for the rule uses two generated Terraform files to verify if the correct msg
field is returned by the rule for allowed and denied fixtures:
Example of a rule
For more examples, see Custom Rules Examples.
For this example, the templated rule was modified to assign a msg
when a resource does not have an owner
tag:
Limitations and notes
As Snyk compiles Rego policies into Wasm modules, you can only use built-in functions that support Wasm. There is a table at the bottom of the Policy Reference Documentation that can help you identify those.
A rule may be defined multiple times with the same name, either in a file or in separate files under the same package, for example,
These rules are referred to as incremental
because each definition is additive. You can read more about Incremental Definitions in the Policy Reference Documentation. Note that these same named rules have to return a different value, or OPA will return an error. You can read more about Complete Definitions in the Policy Reference Documentation.
For more complex topics, check how OPA resolves Conflict Resolution.
Last updated