Ruby::Rego
Ruby::Rego is a pure Ruby implementation of the Open Policy Agent (OPA) Rego policy language. The project targets a clean, Ruby-idiomatic API with strong test coverage and type signatures while working toward broader Rego compatibility.
Project goals
- Provide a stable Ruby API for parsing, compiling, and evaluating Rego policies.
- Offer a deterministic evaluator with clear error reporting.
- Keep compiled modules immutable and safe to reuse.
- Ship a CLI for common validation workflows.
Status
The gem is under active development and does not yet cover the full OPA specification. Please review the supported feature list below before relying on it in production.
Installation
Install the gem and add it to your Gemfile:
bash
bundle add ruby-rego
If you are not using Bundler, install it directly:
bash
gem install ruby-rego
Quick start
```ruby require “ruby/rego”
policy = «~REGO package example default allow = false allow { input.user == “admin” } REGO
result = Ruby::Rego.evaluate(policy, input: => “admin”, query: “data.example.allow”) puts result.value.to_ruby ```
API documentation
Basic parsing
```ruby require “ruby/rego”
tokens = Ruby::Rego::Lexer.new(policy).tokenize ast_module = Ruby::Rego::Parser.new(tokens).parse ```
Policy evaluation
```ruby require “ruby/rego”
compiled = Ruby::Rego.compile(policy) evaluator = Ruby::Rego::Evaluator.new(compiled, input: => “admin”) result = evaluator.evaluate(“data.example.allow”) puts result.to_h ```
Validation use case
```ruby require “ruby/rego” require “yaml”
policy_source = File.read(“examples/validation_policy.rego”) config_hash = YAML.safe_load(File.read(“examples/sample_config.yaml”))
policy = Ruby::Rego::Policy.new(policy_source) result = policy.evaluate(input: config_hash, query: “data.validation.deny”)
if result.nil? puts “No decision” elsif result.success? puts “OK” else puts “Errors: #resultresult.valueresult.value.to_rubyresult.value.to_ruby.inspect” end ```
CLI usage
bash
bundle exec exe/rego-validate --policy examples/validation_policy.rego --config examples/sample_config.yaml
The CLI attempts to infer a validation query in this order: deny, violations, violation, errors, error, then falls back to allow. You can override this with --query.
Supported Rego features
Language support
- Packages and imports.
- Rule definitions (complete and partial rules, defaults, else).
- Literals and references, including input/data.
- Collections: arrays, objects, sets.
- Comprehensions (array, object, set).
- Operators: assignment, unification, comparisons, arithmetic, and boolean logic.
- Keywords:
some,not,every(experimental), andwith(limited).
Built-in functions
Built-ins are currently limited to core categories: types, aggregates, strings, collections, and comparisons. See the builtins registry for the current list.
Known limitations
- Not full OPA spec coverage yet.
- No non-standard destructuring extensions (e.g., rest elements or partial-object remainder capture).
- Advanced
withsemantics, partial evaluation, and additional built-ins are still in progress. - Performance work is ongoing; expect lower throughput than OPA.
Performance and benchmarks
Ruby::Rego focuses on correctness and clarity over raw throughput. Expect performance to scale with
policy complexity: deep references, large comprehensions, and heavy use of with modifiers cost more.
Memoization caches rule outputs and static references during a single evaluation to reduce repeated work.
Comparison with OPA
OPA (Go) is highly optimized and typically faster, especially on large policies or high-throughput workloads. Use Ruby::Rego when you need a pure Ruby runtime or tight integration with Ruby applications, and prefer OPA for latency-critical or batch-heavy policy evaluation.
Tips for performant policies
- Prefer indexed data structures and avoid deep, repeated reference chains.
- Keep comprehensions small; filter early and avoid nested comprehensions when possible.
- Use built-ins like
count,sum, andobject.getinstead of manual loops. - Avoid
withmodifiers on hot paths; they are intentionally isolated and reset memoization caches. - Keep rule dependencies shallow to minimize repeated rule evaluation.
Running benchmarks
Benchmarks use benchmark-ips and live in the benchmark/ directory:
bash
bundle exec ruby benchmark/simple_rules.rb
bundle exec ruby benchmark/comprehensions.rb
bundle exec ruby benchmark/builtin_calls.rb
bundle exec ruby benchmark/complex_policy.rb
CLI profiling
Use --profile to capture timing and memory deltas for compilation and evaluation. Profiling output is
emitted to stderr so JSON output remains machine-readable.
bash
bundle exec exe/rego-validate --policy examples/validation_policy.rego --config examples/sample_config.yaml --profile
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/r6e/ruby-rego.
- Run
bin/setupto install dependencies. - Run tests with
bundle exec rspec. - Run quality checks:
bash
bundle exec rubocop
bundle exec reek lib/
bundle exec rubycritic lib/
bundle exec steep check
bundle exec bundler-audit check --update
Please include tests and documentation updates with your changes.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Ruby::Rego project is expected to follow the code of conduct.