v0.10.0
This release brings a new type of linter rule to Regal — aggregate rules. v0.10.0 also brings a number of new rules, new features, performance improvements and bug fixes.
Aggregate rules
Aggregate rules evaluate input not just from a single Rego policy at a time, but collect, or aggregate, data from all files included for linting. A second evaluation step is then performed where the data collected is used to determine if a linter rule violation occured. Aggregate rules help solve issues at the level of a project rather than individual files, and could for example be used to ensure that at least one package is annotated with an authors
attribute, or that no import
point to a package that doesn't exist in the repo. Since aggregate rules require input from several files, they are disabled by default when linting a single policy file.
Huge thanks to @sesponda (Atlassian) who helped both in the design and implementation of this feature!
While the feature is considered stable, there are still some things to work out for the next release in terms of configuration options and documentation for custom aggregate rules. Join us in the #regal channel if you'd like to be an early adopter!
New rule: prefer-package-imports
Category: imports
The first built-in rule to make use of the new aggregate system is prefer-package-imports
. The Rego Style Guide has long since advocated the use of package level imports over importing rules and functions directly, and now there is a Regal rule to enforce that!
For more information, see the docs on prefer-package-imports.
New rule: no-defined-entrypoint
Category: idiomatic
The next aggregate rule to ship with Regal is no-defined-entrypoint
. Annotating at least one package or rule as an entrypoint is a good practice for documenting your project. And not only that — using an entrypoint annotation unlocks several programmatic capabilities for compilation to other formats, like Wasm, or IR.
For more information, see the docs on no-defined-entrypoint.
New rule: default-over-else
Category: style
The next rule is not an aggregate one, but no less useful! In the style category, the default-over-else
rule will flag "fallback else" conditions in favor of default
assignment.
Avoid
package policy
import future.keywords.if
permisisions := ["read", "write"] if {
input.user == "admin"
} else := ["read"]
Prefer
package policy
import future.keywords.if
default permisisions := ["read"]
permisisions := ["read", "write"] if {
input.user == "admin"
}
A configuration option allows setting default functions (recently introduced in OPA) as a preference as well.
For more information, see the docs on default-over-else.
New rule: rule-length
Category: style
Thanks to some improvements to the OPA AST contributed upstream by @charlieegan3, one class of rules has been made much simpler to implement. One such rule is rule-length
, which similarly to file-length flags when too much is going on in a single location, and in this case a rule or a function body. The default limit is 30 lines, but this can be changed in the configuration to your liking.
For more information, see the docs on rule-length.
Feature: regal lint --enable-print
The regal lint
command now accepts an --enable-print
flag to simply allow print
statements without printing other debugging information.
Feature: regal lint --profile
Similarly to the profiling capabilities in OPA, Regal now provides a --profile
flag to help collect and report profiling data, helping policy authors and Regal developers to see where most of the time is spent in evaluation.
Experimental: Wasm/Wasi compilation
Friend of Regal @srenatus has contributed some experimental code to compile Regal to Wasm/Wasi. See the development docs if you're curious to try it out!
Performance improvements
- Regal now uses a custom algorithm to filter out files ignored, up to 30X faster than previously.
- OPA dependency bumped to point to
main
which includes performance improvements towalk
and arithmetic operations.
Other improvements
- The
regal new rule
command now adds both a documentation page and an entry in the README table. Thanks @Ronnie-personal for contributing! - A
non-breakable-word-threshold
option has been added to theline-length
rule, which allows tolerating single words that exceed the line length if they can't be broken up into several parts, like URLs. Thanks @iamleot for requesting this! - The
top-level-iteration
incorrectly identified constants and other parameters as iteration. This was identified and fixed by @zregvart. Thanks!
Great to see so many old and new faces in the list of contributors. Thank you all!
Changelog
- 82ebbe6: File filtering improvements (#332) (@anderseknert)
- bbdceb7: Add
--enable-print
flag toregal lint
(#337) (@anderseknert) - 0098ff7: Implement Aggregates Collection and Usage (#323) (@sesponda)
- 938172a: Allow parameters and constants in top level rule (#347) (@zregvart)
- 9063cf0: build: add kludges to build for WASI (#346) (@srenatus)
- 590ce2e: Rule:
prefer-package-imports
(#349) (@anderseknert) - 41e127d: Add
non-breakable-word-threshold
option toline-length
rule (#350) (@anderseknert) - 716a574: Bumping opa to v0.57.0 (#352) (@johanfylling)
- de17845: Rule:
rule-length
(#354) (@anderseknert) - 57d77d1: Remove code that set the ref head env var (#353) (@anderseknert)
- c937e34: Remove rule.head.name usage (#357) (@anderseknert)
- 52c57d3: Rule:
default-over-else
(#360) (@anderseknert) - f1ff4fb: Rule:
no-defined-entrypoint
(#355) (@anderseknert) - 58bb7b8: Add config and README entry with
regal new rule
command (#304) (@Ronnie-personal) - 28a51f7: Add
--profile
option toregal lint
(#361) (@anderseknert) - e4fb086: Bump OPA version to current main (#362) (@anderseknert)