- Add cfg(not(miri)) guards to mimalloc module, global allocator, and
allocator-memory-limits code paths so Miri falls back to the default
system allocator instead of calling unsupported FFI functions.
- Set MIRIFLAGS="-Zmiri-disable-isolation" in the workflow so tests
that perform file I/O can run under Miri.
- Skip units/parse tests under Miri due to Float-vs-BigInt Number
representation mismatch with Miri's soft-float emulation.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Introduce ExecutionTimer/ExecutionTimerConfig to allow limiting evaluating time.
- To amortize time checking costs, checking interval can be configured via the notion of work units
- A global fallback time limit can be set to universally limit all evaluation in addition to engine level limit setting.
- Implement limnits in interpreter and RVM. In RVM, also handle suspend/resume so that time during pause is not counted.
- Add engine-level APIs to set/clear per-engine timer configuration and apply global fallback defaults.
- Surface execution-time limits through FFI and C# bindings
- Add C# tests and example usage to validate engine overrides, global fallback behavior, and compiled policy enforcement.
- Expand docs for execution-time limit
- Add interpreter YAML cases and VM unit tests for time-limit behavior and deterministic time sources.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Policy evaluation at scale needs to be able to set memory limits
so that a bad policy does not hog memory or to ensure that
policy evaluation itself does not use too much memory which could
cause other components to suffer.
This PR introduces capability to set and enforce global memory limits.
It also lays the groundwork for enabling per evaluation limits in future.
Once a global memory limit is set, Regorus maintains per thread counters
to track memory activity (allocation, deallocation) of a thread.
These counters are periodically flushed to global memory counters.
Per thread counters avoid the contention that updating global counters
on each alloc/free would cause.
Policy evaluation periodically checks these counters and raises errors
if allocated memory has exceeded the configured limit.
Currently memory limit capability is exposed only to FFI and C#.
Also update mimalloc to v2.2.6
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Made the lookup module crate-visible to address clippy’s redundant visibility lint.
- Replaced unchecked as casts with a fallible usize_from_u32 helper and propagate conversion errors in lookup accessors.
- Switched LookupIndexError to implement core::error::Error for no_std correctness.
- Fixed the pattern type mismatch by matching on the value in the Display impl.
- Promoted trivial helpers to const fn (new, module_len) per clippy suggestions.
- Centralized bounds-checked slot access via slot_ref/slot_mut to keep getters/clearers lint-clean and avoid unchecked indexing.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Lints are added (deny) at crate level.
In each offending file, the failing lints are explicitly allowed.
Each file will be fixed in subsequent PRs.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* feat: Add Azure RBAC condition parser
- declare an `azure-rbac` feature and expose the Azure RBAC module with parser, AST, and YAML-driven tests
- extend the shared lexer with RBAC-specific tokens, single-quoted strings, and corrected raw-string spans
- verify the parser via comprehensive test cases covering every operator and complex chaining
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
---------
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* feat!: add Rego Virtual Machine (RVM) implementation
This commit introduces a register-based virtual machine for executing Rego
policies with bytecode-style instructions. Unlike the existing tree-walking
interpreter, the RVM compiles policies into instruction sequences that operate
on virtual registers, offering better performance and optimization potential.
Core Components:
Instruction Set Architecture:
- Define instruction types for data operations, control flow, and builtins
- Implement instruction parameter encoding and display formatting
- Add instruction parser with comprehensive test coverage
Virtual Machine Engine:
- Register-based execution model with program counter management
- Loop execution supporting iterators, comprehensions, and quantifiers
- Function call handling with argument evaluation and context management
- Rule evaluation with default value resolution and virtual data support
- Arithmetic and comparison operation implementations
Program Representation:
- Program listing builder with instruction sequencing
- Rule tree construction for organizing policy rules
- Binary and JSON serialization for compiled programs
- Recompilation support for program modification
Testing Infrastructure:
- Extensive YAML test suites covering all VM features
- Rust unit tests for VM execution and instruction parsing
- Test suites for loops, comprehensions, builtins, and control flow
BREAKING CHANGE: Introduces new VM execution path alongside interpreter
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* docs: add detailed RVM architecture references
Introduce architecture.md explaining program artifacts, serialization, and runtime subsystems.
Document the full opcode catalog in instruction-set.md, including operands, parameter tables, and outcomes.
Walk through execution flow, stacks, and operational guidance in vm-runtime.md, tying the runtime to the new architecture docs.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
---------
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- add a dedicated `compiler/destructuring_planner` feature that precomputes binding plans for assignments, parameters, and `some in` expressions
- enrich `ScopeContext` with same-scope tracking, local scheduling hints, and module globals so the planner enforces := shadowing rules without blocking parent scopes
- wire the planner through compiler, hoist, interpreter, and engine paths while updating binding plan variants and adding query traversal helpers for dependency analysis
- document the new planner architecture and ship interpreter regressions that exercise nested destructuring, shadowing, and error reporting
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Introduce a compiler pass that analyzes and pre-computes loop hoisting information
during policy compilation. This hoisted metadata is stored in lookup tables and made
available to downstream consumers:
- interpreter: use HoistedLoop entries during evaluation (replaces runtime scanning)
- type inference: can leverage pre-computed loop structure for type propagation
- RVM compiler: will consume hoisting metadata for optimized bytecode generation
Changes:
- populate loop hoisting tables during engine preparation and query snippet execution
- refactor eval_stmts_in_loop and eval_output_expr_in_loop to consume HoistedLoop directly
- add helper methods for accessing loop expressions, collections, and indices from HoistedLoop
- extend Lookup with get_checked and into_slots for safe query context access and merging
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Major Changes:
- Add generic Lookup<T> structure for efficient O(1) module-level data access
- Combine separate scope and order lookups into unified QuerySchedule structure
- Add query_schedule field to Interpreter for dedicated user query scheduling
- Refactor loop hoising to separate module
- Use efficient lookup for loop vars
- Also added more tests for loops
Key Concept:
- Ensure module context and indexing stay synchronized during function calls
Testing:
- All scheduler and interpreter tests passing
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Details:
- Implement complete Type enum with 12 variants: Any, Integer, Number, Boolean,
Null, String, Array, Set, Object, Enum, Const, AnyOf
- Add Schema wrapper struct with reference counting for efficient sharing
- Support JSON Schema-compatible deserialization with serde
- Implement discriminated subobjects for polymorphic type definitions
- Add comprehensive test suite covering all type variants
- Include Azure resource schema examples (Storage, VM, Key Vault, App Service)
- Create meta-schema validation system with lazy static validator
- Add extensive edge case and corner case test coverage
- Implement custom deserializers for complex schema patterns
This establishes the foundation for type checking and validation of Rego
policies, particularly useful for cloud resource schemas and policy validation.
Regorus's type system is a first of many features intended to
enable type checking and various other constraints on Rego policies.
The type system is inspired from:
- JSON schema
- Bicep
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Indexes allow associating extra data with nodes in the AST
using an array and then quickly looking up the array to fetch
the extra data.
- Index eidx for expressions
- Index sidx for statements
- Index qidx for queries.
AST nodes are not cloneable. Therefore once a module is created,
it is not possible to accidentally create two nodes with the same
index inadvertently via clone.
Also added IndexChecker in debug builds. When a module is parsed,
it will assert that indexes have been constructed correctly.
AST Cleanup
- Make literal expressions (null, val, number, string etc) also structs
to match all other expressions
- Merge True and False nodes into a single Bool node.
Also update dependencies.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Earlier scheduler only recognized rules and would raise an
`unsafe var` error on alias.
Register alias var names to fix this.
fixes#284
Also fix clippy warning treated as error
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- c, cpp
- csharp
- ffi
- go
- Java
- Python
- WASM
`arc` feature is turned on for all bindings
Use pretty string instead of colored string.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Disable default features in dependencies
- Use anyhow::Error::msg to map errors. Note: anyhow will itself be removed later.
- lazy_static/spin_no_std used in no_std environments
- ensure_no_std binary is built to target thumbv7m-none-eabi to ensure that
there are no std dependencies. thumbv7m-none-eabi target has no std support.
- The opa-no-std feature enables only those Regorus features that work with no_std.
- Enable tests with no_std
- Update sizes of regorus binary in README.md
- Ensure that regorus example can be built with only std
- Ensure that regorus example can be built with no_std
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- `std` feature is enabled by default
- By default enable #![no_std] compilation
- Import std create if `std` feature is enabled or if testing
- Use core, alloc types
- Make it clear where std types are being used
- In no std, use BTreeMap in place of HashMap.
HashMap is not available in no std due to lack of a
secure random number generator
Note: The project does not yet compile without std feature being specified.
But it's really close to being able to do so.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Replace std with alloc, core in most places in src
Tests, bindings aren't changed.
- Introduce BuiltinsMap type alias inplace of HashMap.
In no_std case, this could be aliases to BTreeMap
- Fix clippy warnings
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* `arc` feature to make engine usable from multiple threads.
`arc` is turned on by default. When enabled, std::sync::Arc
will be used instead of std::rc::Rc. The former makes regorus
types like Engine, Value, ast nodes etc Send, allowing for
usability from multiple threads.
Arc would add a performance overhead though since the reference
counting will now become atomic.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* Make engine and related types Debug
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
* Input, Data as json. Evaluate bool queries.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
---------
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
- Separate out public, unstable and internal APIs.
- Cleanup README.md and include it as the crate documentation.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Number is implemented using rust_decimal::Decimal which uses a 96 bit mantissa.
TODO:
a) Support u64, i64 variants
b) Determine desired semantics for floating-point
c) Determine desired big integer length
d) Explore other big int/big float crates
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This allows holding onto objects, caching results etc easily.
However it does introduce the overhead of ref counting.
Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>