Skip to content

Releases: open-policy-agent/regal

v0.39.0

26 Feb 19:02
23614cc

Choose a tag to compare

We're happy to announce Regal v0.39.0, featuring 3 new linter rules, many language server improvements, and much faster linting!

New Rule: use-array-flatten

Category: idiomatic

The use-array-flatten rule recommends using array.flatten instead of nested array.concatenation (#1873).

Avoid

package policy

flat1 := array.concat(arr1, array.concat(arr2, arr3))

flat2 := array.concat(arr1, array.concat(arr2, array.concat(arr3, arr4)))

Prefer

package policy

flat1 := array.flatten([arr1, arr2, arr3])

flat2 := array.flatten([arr1, arr2, arr3, arr4])

New Rule: use-object-union-n

Category: idiomatic

The use-object-union-n rule recommends using object.union_n over nested calls to object.union (#1873).

Avoid

package policy

obj := object.union(obj1, object.union(obj2, obj3))

Prefer

package policy

obj := object.union_n([obj1, obj2, obj3])

New Rule: equals-over-count

Category: performance

The new optional equals-over-count rule suggests using direct equality comparisons rather than count when checking collection membership or emptiness (#1878). This is a micro-optimization and not a general recommendation. Must be manually enabled.

Performance

This release brings an approximate 25% reduction in linting time through aggregate remodeling and Rego prepare stage optimizations (#1838). Additional performance work includes Rego refactoring (#1857, #1884), AST transform improvements (#1892), and various micro-optimizations (#1866, #1879).

Language Server Improvements

The language server now includes a semantic token framework for improved syntax highlighting (#1845, #1865, #1870),
code actions for the constant-condition and redundant-existence-check fixers (#1830).
and an opaTestProvider feature for test discovery (#1888, #1889, #1898),

Completion performance is improved with a completionItem/resolve handler (#1831),
and server capabilities are now properly exposed and consistent with the clients (#1867, #1880).

Note: Semantic token support is feature flagged and will be available in the next release.

Compiler Explorer

Regal now supports the VSCode-based OPA Explorer extension, providing a rich GUI to compare compiler stages directly in VS Code (#1862) - thanks @srenatus! A new "Format stages" option has also been added to the compiler explorer (#1854) - thanks @johanfylling!

Experimental: rq Engine Support

Initial support for the rq engine has been added (#1872) - thanks @charlesdaniels!

Various Improvements

  • Improved redundant-existence-check rule (#1897, fixes #1805)
  • Disabled zero-arity-function rule as opa-fmt now covers that (#1885)

Bug Fixes

  • Fix nil dereference on compiler errors in explorer (#1837)
  • Fix broken links to fixer page (#1852)
  • Fix false positive in use-some-for-output-vars (#1886)
  • Fix broken input.json completion provider (#1891)

Dependency Updates

Regal has been upgraded to use OPA v1.14.0 and Go 1.26.

Documentation

  • Added mise as an alternative installation method (#1849) - thanks @jylenhof!
  • Updated installation documentation (#1861)
  • Updated note about eval and debug roots (#1894)
  • Show release badge when using pre-release versions (#1899)

New Contributors

v0.38.1

13 Jan 15:39
fd6dd4d

Choose a tag to compare

This patch release fixes several bugs including some found in the recent v0.38.0 release, as well some other improvements.

Bug Fixes

  • Fix for prefer-equals-comparison fixer failing to parse policies with multiple "=" in expressions (#1824, fixes #1818 reported by @gusega)
  • Fix for incorrect fixable violation count display in lint output (#1825, fixes #1813 reported by @gusega)
  • Fix for false positive in prefer-equals-comparison rule with comprehension term vars (#1828, fixes #1826 reported by @SeanLedford)
  • bundle: Surface configured rule notices as messages in lint output (#1827, fixes #1795 reported by @ghmer)

Improvements

  • Code action for prefer-equals-comparison fixer now available in the language server (#1810)
  • New option for prefer-value-in-head rule to count interpolated strings as scalars (#1817)
  • Minor performance improvement for any_set_item, used for selecting items from sets (#1815)

Changelog

v0.38.0

08 Jan 18:40
a9843ab

Choose a tag to compare

Happy New Year from the Regal maintainers!

Feature: String Interpolation Support

v0.38.0 of your favorite Rego linter, debugger and language server brings full support for OPA's new string interpolation feature. This means not only that Regal lints code found inside interpolated strings, but that you'll have access to all your favorite language server features within them too — like code completions, tooltips on hover, or document highlighting. You can even use the debugger to step through interpolated expressions! If you haven't yet tried it out, grab OPA v1.12.2, Regal v0.38.0 and enjoy an absolutely awesome addition to the Rego language!

In addition to this, we have a number of fun new features and performance improvements.

New Rule: disallow-rego-v1

Category: custom

This optional new rule flags the use of import rego.v1 in Rego policies (#1778). Since OPA v1.0 (December 2024), this import is a no-op and no longer needed. The rule helps users maintain clean code by preventing this outdated import from appearing in new policies. Teams standardizing on OPA 1.0+ can enable this rule to enforce modern Rego standards.

package example

import rego.v1 # <-- Happy 2026! Time to stop doing this!

Authored by @SeanLedford.

New Fixers

@SeanLedford has also done some great work to help expand Regal's auto-fixing capabilities by having regal fixers added for three more rules.

See (#1790) and (#1794) for more details.

Performance

The fixer saw a 12% performance improvement by reusing the linter, reducing allocations from 2.3M to 2.0M operations (#1783). Additional optimizations include:

  • faster file filtering by avoiding recompiled ignore patterns (#1758),
  • better built-in function handling by registering Regal's functions globally only once (#1788),
  • and more efficient AST location serialization (#1758)

To track ongoing performance work, a new post-merge benchmark-recording workflow was added (#1793).

LSP: New Ignore Code Action

The language server now supports a code action to quickly add regal ignore configuration for specific rules directly from the editor (#1777).

Changelog

v0.37.0

06 Nov 17:53
216341a

Choose a tag to compare

Regal v0.37.0

This release features a new linter rule, several new language server features, and many improvements and fixes. The two major OPA versions bumped since the last release additionally contains several performance improvements that were contributed as part of developing Regal!

New Rule: prefer-equals-comparison

The prefer-equals-comparison linter rule recommends using the == operator for equality comparison over the unification operator =. The rule helps improve code clarity by using operators for their intended purposes: := for assignment, == for equality comparison, and = for unification. The linter identifies when = is used for comparison by checking if both sides of the operator are "unassignable".

Avoid

input.request.method = "GET"

Prefer

input.request.method == "GET"

There are some certainly valid use cases for the unification operator! But simple equality comparison is not one. For more information, see the documentation for the rule. As an amusing aside, this fixes one of the first issues created in the project!

Language server: Document highlighting to help show where function args are referenced

Document highlighting is one of the more subtle features of the LSP specification, but a really helpful one when implemented well. The experimental first implementation that shipped with Regal v0.36.0 is no longer experimental, and has also been extended to highlight usage of function argument variables inside of a function head or body.

documenthighlighting

Language server: Selection ranges

Selection ranges provide smart selection of code that can expand and shrink based on knowledge of the code rather than simple text properties, like hyphens or whitespace. This makes moving code around extremely fast, and without leaving the keyboard. Consult the language server docs for how to enable this in your editor

selectionranges

Improvements

  • The pointless-reassignment rule would previously only flag reassignment at the top level of a rule body. Now it flags pointless reassignments also in nested bodies, like comprehensions, every statements, and so on.
  • All completion providers are now implemented purely in Rego
  • Remove the go-semver dependency in favor of a custom, much faster implementation
  • Build: Reduce permissions granted in update-caps top-level workflow, by @timothyklee
  • Docs: Update language server page to demonstrate recently added features
  • Docs: Add kakoune LSP configuration example

Windows compatibility improvements

In this release we have fixed various Windows bugs (Language Server Init, Goto Definition, Error Popups) in #1740, #1737, #1736, following #1633, and #1642 last release. Reported and verified by geirs73.

These fixes have also made it possible to run our test suites on Windows runners to catch issues sooner in future. A huge thanks to @charlieegan3 for his tireless work on this!

Bugs fixed

Dependency Updates:

Go modules:

  • github.com/open-policy-agent/opa: v1.8.0v1.10.1
  • github.com/arl/statsviz: v0.7.1v0.7.2
  • github.com/go-git/go-git/v5: v5.16.2v5.16.3
  • github.com/olekukonko/tablewriter: v0.0.5v1.1.0
  • github.com/spf13/cobra: v1.9.1v1.10.1
  • github.com/spf13/pflag: v1.0.7v1.0.10
  • Removed: github.com/coreos/go-semver: v0.3.1

GitHub Actions:

  • open-policy-agent/setup-opa: v2.2.0v2.3.0
  • actions/cache: v4.2.4v4.3.0
  • actions/upload-artifact: v4.6.2v5.0.0
  • golangci/golangci-lint-action: v2.4.0v2.5.0
  • actions/setup-go: v5.5.0v6.0.0

Support

If you encounter any issues with this release, please either file an issue, or let us know in the #opa-regal channel in the OPA Slack!

Changelog

Read more

v0.36.1

10 Sep 14:09
1f1044f

Choose a tag to compare

This is Regal v0.36! The first Regal release since becoming a part of the OPA project last month. This release mostly delivers a number of new language server features as well as wider improvements under the hood and to the developer experience.

A note for users getting Regal via Homebrew

Since Regal was made an official formula, our recommendation has been to use that as your source for Regal. This is the first release distributed only via that formula, so if you still rely on the old styrainc/regal one, make sure to have that removed and brew install regal instead.

A note about Regal's documentation

Our documentation is now displayed as part of the main OPA website!

https://www.openpolicyagent.org/projects/regal

From this release, links generated from Regal in output to rules will point to this location. You might find links to the old location as we get things updated. Please feel free to open any issues for link problems you find just so we don't miss anything.

Get contextual documentation when calling built-in functions

Following PR #1654, the Regal language server will now offer signatureHelp to compatible clients. This shows the current argument type and description in the help text for built-in functions. This is in addition to the other general function documentation displayed here.

ScreenRecording2025-09-09at14 06 54-ezgif com-video-to-gif-converter

Quickly see related fields in when editing METADATA

PR #1657 implements support for the documentHighlight request from clients. This is currently only used to show signal other related METADATA keys when working with Rego metadata.

ScreenRecording2025-09-09at11 12 34-ezgif com-video-to-gif-converter

In future, this same functionality could be used to highlight other related items currently in the viewport.

Jump directly from ignore directives to documentation

documentLink is another request from clients which allow the server to respond with link ranges. We have used this to make regal ignore directives clickable, helping users quickly learn what they mean when encountered in policies PR #1657.

ScreenRecording2025-09-09at14 03 06-ezgif com-video-to-gif-converter

Get live diagnostics from custom rules as you type

PR #1631 ensures that users of custom linter rules are also able to access these for live diagnostics in language server clients. Previously these were not evaluated in the server, only in the Regal CLI.

ScreenRecording2025-09-09at11 34 01-ezgif com-video-to-gif-converter

Notable Refactors & Development Changes

  • Rego Language Server Routing: PR #1675 makes some notable changes to how Rego is used within the Regal’s language server. The Language Server Protocol (LSP), which Regal implements to support LSP clients, is based on JSON message passing. This lends itself to Rego evaluation which is JSON in, JSON out. This PR updates the handling of different LSP messages sent from clients to route them in Rego, handling Rego backed rules first, and falling back to Golang implementations that still remain otherwise. This sets the direction for more Rego LSP functionality in the language server in future.
  • Development bundle loading from disk: PR #1646 gives those working on Regal in development the option of using the current source for the Regal bundle without rebuilding the binary. This improves the experience when working on Rego based language server functionality by reducing the time of a feedback loop. Set REGAL_BUNDLE_PATH to use this feature.

Changelog

Read more

v0.35.1

30 Jun 17:40
92d1ba9

Choose a tag to compare

We're happy to release v0.35.1, the mid-summer release of Regal for the 🏖️ ! This release updates to OPA v1.6.0 bringing a number of performance improvements as well as other improvements and bug fixes.

Improved Schema Loading

This PR replaces Regal's custom schema loader with one that matches OPA's behavior, enabling the same schemas to work across opa check, opa eval, and other OPA commands. PR #1605

Performance Improvements

  • Thanks to a PR in OPA, Regal's memory use is now much reduced due to a change conditionally supplying built-in contexts only when needed.
  • This PR optimizes Rego evaluation by directly mapping source data to ast.Value objects instead of going through intermediate map[string]any or JSON representations, eliminating ~2.9 million allocations in benchmarks. PR #1606
  • Regal contributors will be happy with open-policy-agent/opa#7442 which makes running Regal's tests around 2.5x as fast!

Code Actions Rewrite

Code actions are LSP features that provide automated fixes or refactoring suggestions (like "quick fix" options), and this PR implements them for Regal with server-side filtering to reduce data transfer and ensure consistent editor behavior. This is also now implemented in Rego! PR #1604

Docs

  • PR #1584 refactors a number of Regal's pages including breaking down the previously large README into separate files. Browse the new structure on the Regal Website.
  • The Code Lens documentation has been updated to better explain supported configurations. Thanks @Shinzu for the report here. #1596

Changelog

v0.34.1

04 Jun 12:44
f4e4bc3

Choose a tag to compare

This patch release fixes a bug found since v0.34.0 as well as it bumps the OPA dependency to the v1.5.1 patch also released today. While Regal's own policies were not affected by the regression in walk, custom linter rules could very well be.

  • OPA v1.5.0 -> v1.5.1
  • Go 1.23 -> 1.24
  • Fix false positive in sprintf-arguments-mismatch when the %-*s pattern was used for padding.

Changelog

v0.34.0

30 May 13:07
47c70f0

Choose a tag to compare

After a month of development, we're happy to announce Regal v0.34. This version of the OPA community's favorite linter and language server brings you new 3 linter rules, performance improvements and much more.

With the v0.34.0 release, Regal now ships with more than 100 linter rules! 🎉
Which is pretty close to one new rule per week since the project started.

New rules

unresolved-reference

Category: imports

This one is particularly exciting! The new unresolved-reference rule reports any references (like data.users.permissions) that cannot be resolved (i.e. found) anywhere in the project. Some projects will have valid references that can't be resolved at the time Regal lints the project, and the rule provides configuration options to mark certain references, or entire paths (like data.users.*) as resolved. See the docs for the rule for more details.

This rule was contributed by @HookFirebolt and @bdumpp at Bankdata. Great work, and thank you both!

pointless-import

Category: imports

The new pointless-import rule will flags imports of the same package, and other import forms where the import has no real effect.

single-item-in

Category: idiomatic

The single-item-in rule reports cases of in being used on a single item collection, and suggests using an equality check instead.

Performance

  • Use OPA v1.5.0, which brings performance improvements to walk reducing linting time by about 10%.
  • Faster linting by avoiding walk in a few locations where possible.
  • Improve performance of aggregate rules.
  • Several performance optimizations to Regal's linter rules.

API

  • The linter API now has a new Prepare method that can be used to prepare the linter before reusing it across several runs.

Various

  • Some rules that would previously only scan the topmost level of a rule body will now recursively scan the whole rule.
  • The input completions provider has been rewritten in Rego (previously Go).
  • The automatic version check has been rewritten in Rego (previously Go).

Bugs

Docs

Changelog

v0.33.1

22 Apr 13:01
61e8bf6

Choose a tag to compare

This release adds 4 new linter rules to Regal, alongside significant performance improvements and several bug fixes.

New Rule: in-wildcard-key

Using a wildcard variable (_) for the key in the key-value form of iteration (some _, value in collection) is never needed, and can be replaced by the simple some value in … form . This rule flags cases where the key iteration is redundant. (Read more)

package policy

allow if {
    # Avoid: key iteration ('_') is redundant if only 'user' is used
    some _, user in input.users
    # do something with each user
}

allow if {
    # Prefer: clearer intent when only iterating values
    some user in input.users
    # do something with each user
}

PR #1466

New Rule: confusing-alias

While import aliases can improve readability, aliasing an import reference that is also imported without an alias is confusing, as both names point to the same resource. This rule catches such cases. (Read more)

package policy

# Avoid: both 'users' and 'employees' point to data.resources.users
import data.resources.users
import data.resources.users as employees

# Prefer: a single import for any given resource
# import data.resources.users

PR #1470

New Rule: mixed-iteration

Rego supports different styles of collection iteration. While "reference style" iteration (collection[_]) can be concise for deeply nested structures, mixing it with the some .. in style within a single iteration expression makes for code that’s more difficult to follow. This rule encourages consistency within a single iteration statement. (Read more)

package policy

allow if {
    # mixing 'some .. in' and reference iteration
    some resource in input.assets[_]
    # do something with resource
}

allow if {
    # using 'some .. in' iteration consistently
    some asset in input.assets
    some resource in asset
    # do something with resource
}

PR #1475

New Rule: narrow-argument

This new rule analyzes function arguments to suggest narrowing them down to the minimal value the function depends on. This can improve clarity and reusability. The rule considers incrementally defined functions across all their definitions. This is a powerful but opinionated rule and is thus in the custom category and is not on by default. See the documentation for how to enable it if you’re curious to try it out! (Read more)

package policy

# Avoid: the function only uses the 'email' property of the 'user' object
valid_user(user) if endswith(user.email, "acmecorp.com")
valid_user(user) if endswith(user.email, "acmecorp.org")

# Prefer: narrowing the argument to only what the function needs
valid_email(email) if endswith(email, "acmecorp.com")
valid_email(email) if endswith(email, "acmecorp.org")

PR #1488

Performance Improvements

Several improvements have been made to reduce memory allocations and improve overall linting performance. Numbers below refer to Regal’s benchmark for linting its own policies.

  • Optimized config loading and parsing, saving around 2.7 million allocations (#1491).
  • Reduced allocations by approximately 2 million (#1494).
  • Improved the performance of the use-strings-count rule, saving almost 1 million allocations (#1465).
  • Optimized reference comparisons and small iteration patterns, saving around 300k allocations (#1472).
  • Included performance enhancements alongside an update to the external-reference rule to make it more configurable (#1496).

OPA v1.3.0

Regal has been upgraded to use OPA v1.3.0. This brings several upstream improvements, including support for the new one-liner grouping in formatting (see OPA#6760). (#1459)

Bug Fixes

  • Fixed a bug in the handling of Rego input from stdin. Thanks @tokyowizard for the report! (#1474)
  • Fixed a panic that could occur in FindConfigRoots when supplied with unexpected arguments. (#1487)

Other Rule Updates

  • The external-reference rule can now be configured with a maximum number of allowed external references, instead of solely flagging all external uses within a function. If you previously had this rule disabled, you might want to try enabling it now, and possibly tweak its configuration to your liking. (#1496)
  • The rule-length rule now has a separate setting (max-test-rule-length) with a higher default value (60 vs 30) for test rules, acknowledging that tests often include substantial data. (#1476)
  • Updated documentation for the rule-named-if rule based on community feedback received via the page feedback form (please let us know if you see issues! & thanks for the report!) (#1463)

Dependencies

This release also updates Regals dependencies as follows.

Go Mod:

GitHub Actions:

Changelog

Read more

v0.33.0

22 Apr 12:26
61e8bf6

Choose a tag to compare

This release is the same tag as v0.33.1, please see that release for the release notes.

Another v0.33.1 was released to trigger the rebuilding of some assets that were deleted in a draft release.