Regolix
Elixir wrapper for Regorus, a fast Rego policy engine written in Rust.
Installation
Add regolix to your list of dependencies in mix.exs:
def deps do
[
{:regolix, "~> 0.3.0"}
]
end
A precompiled NIF is downloaded for your platform — no Rust toolchain required
to use the library. Supported targets: {x86_64,aarch64}-apple-darwin and
{x86_64,aarch64}-unknown-linux-gnu. To build from source instead, set
REGOLIX_BUILD=1 before compiling.
Usage
# Create a new engine
{:ok, engine} = Regolix.new()
# Add a policy
{:ok, engine} = Regolix.add_policy(engine, "authz.rego", """
package authz
default allow = false
allow if input.user == "admin"
""")
# Set input data
{:ok, engine} = Regolix.set_input(engine, %{"user" => "admin"})
# Evaluate a query
{:ok, true} = Regolix.eval_query(engine, "data.authz.allow")
Bang Variants
All functions have bang variants that raise on error:
engine =
Regolix.new!()
|> Regolix.add_policy!("authz.rego", policy)
|> Regolix.set_input!(%{"user" => "admin"})
result = Regolix.eval_query!(engine, "data.authz.allow")
Adding Data
Use add_data/2 to provide external data to your policies:
{:ok, engine} = Regolix.add_data(engine, %{
"users" => %{
"alice" => %{"role" => "admin"},
"bob" => %{"role" => "viewer"}
}
})
Clearing Data
Clear all data while keeping policies loaded:
{:ok, engine} = Regolix.clear_data(engine)
Introspection
Check which packages are loaded:
packages = Regolix.get_packages(engine)
# => ["data.authz", "data.rbac"]
Get metadata about rules defined in policies:
{:ok, rules} = Regolix.get_rules(engine)
# => %{
# "authz.rego" => [
# %{name: "allow", description: "Allow admin users", start_line: 5, end_line: 8}
# ]
# }
This is useful for mapping coverage line numbers to human-readable rule names.
Coverage Tracking
Track which policy lines are executed during evaluation:
{result, coverage} = Regolix.with_coverage(engine, fn e ->
Regolix.eval_query!(e, "data.authz.allow")
end)
# coverage => %{"authz.rego" => %{covered: [1, 2, 5], not_covered: [9, 10]}}
For multi-query accumulation, use the raw primitives:
engine = Regolix.enable_coverage!(engine)
Regolix.eval_query!(engine, "data.authz.allow")
Regolix.eval_query!(engine, "data.rbac.check")
coverage = Regolix.get_coverage_report!(engine)
engine = Regolix.disable_coverage!(engine)
API Reference
new/0- Create a new policy engineadd_policy/3- Add a Rego policyadd_data/2- Add data document (merges with existing)set_input/2- Set input document (replaces previous)eval_query/2- Evaluate a Rego queryclear_data/1- Clear all data (keeps policies)get_packages/1- List loaded package namesget_rules/1- Get rule metadata (names, descriptions, line ranges)with_coverage/2- Execute with coverage trackingenable_coverage!/1- Start recording coveragedisable_coverage!/1- Stop recording coverageget_coverage_report/1- Get coverage dataclear_coverage!/1- Clear coverage data
All functions return {:ok, result} or {:error, %Regolix.Error{}}. Bang variants (new!, add_policy!, etc.) return the result directly or raise.
Rego Syntax
Regolix uses Regorus which implements Rego v1 syntax. Rules require the if keyword:
package authz
default allow = false
allow if {
input.user.role == "admin"
}
allow if {
input.user.role == "viewer"
input.method == "GET"
}
Releasing
Releases are automated. Pushing a vX.Y.Z tag builds the precompiled NIFs,
creates a GitHub release, and publishes to Hex — pausing for a manual approval
before anything ships. You never hand-build checksums or re-tag.
One-time setup. Hex no longer mints API keys from the CLI (auth is OAuth);
generate one at hex.pm/dashboard/keys with the
api permission, then store it scoped to the hex environment:
gh secret set HEX_API_KEY --env hex --repo jtippett/regolix
To cut a release, run the release assistant from master and follow the
prompts:
just release # or, without just: elixir scripts/release.exs
It shows the current and published versions, asks for a patch / minor / major
bump (you pick the level — no version numbers to type), rolls the
CHANGELOG.md[Unreleased] section into the new version, then commits, tags,
and pushes. That kicks off release.yml, which builds NIFs for all four targets
and creates the GitHub release. (The first precompiled release must be a new
version — 0.3.0 is already on Hex as a source build.)
Then approve the publish: open the workflow run → Review deployments →
approve the hex environment. On approval it generates
checksum-Elixir.Regolix.Native.exs from the released artifacts and runs
mix hex.publish.
Keep notes under ## [Unreleased] in CHANGELOG.md as you work — the assistant
rolls them into each release. Don't commit the checksum file or move a published
tag by hand; the pipeline owns both.
License
MIT