Skip to content

feat(ffi): add Azure Policy JSON compilation FFI and C# bindings#720

Open
anakrish wants to merge 3 commits into
microsoft:mainfrom
anakrish:anakrish/azure-policy-json-ffi
Open

feat(ffi): add Azure Policy JSON compilation FFI and C# bindings#720
anakrish wants to merge 3 commits into
microsoft:mainfrom
anakrish:anakrish/azure-policy-json-ffi

Conversation

@anakrish
Copy link
Copy Markdown
Collaborator

This PR exposes Azure Policy JSON compilation through the FFI layer and C# bindings, enabling callers to compile and evaluate Azure Policy definitions natively without translating to Rego first.

What's new

Three new FFI entry points:

  • regorus_compile_azure_policy_rule and regorus_compile_azure_policy_definition parse and compile JSON policy rules/definitions into RVM programs, with optional alias resolution via the existing RegorusAliasRegistry.
  • regorus_rvm_set_context lets callers supply ambient host data (subscription(), resourceGroup(), etc.) that context-dependent policies need at evaluation time.

On the C# side, there's a new AzurePolicyCompiler helper class and a Rvm.SetContextJson method, along with tests and README docs.

Notable choices

  • set_context validates that the JSON is an object (returns InvalidDataFormat otherwise) and persists across executions, matching the existing set_input behavior.
  • The compile functions accept a null registry for simple policies that don't use aliases — this is documented with clear warnings about the implications.
  • Uses Rc::try_unwrap to avoid cloning the compiled program when the refcount is 1 (the common case).
  • Everything is behind #[cfg(feature = "azure_policy")].
  • FFI crate version bumped to 0.10.1.

Add two new FFI functions for compiling Azure Policy JSON directly:
- regorus_compile_azure_policy_rule: compiles a policyRule JSON object
- regorus_compile_azure_policy_definition: compiles a full policy definition

Add regorus_rvm_set_context for setting VM context (subscription,
resourceGroup, etc.) needed by context-dependent policies.

C# bindings:
- AzurePolicyCompiler static class with CompilePolicyRule/CompilePolicyDefinition
- Rvm.SetContextJson method with persistence and validation docs
- Comprehensive test suite (16 tests)
- README documentation with usage examples

Key design decisions:
- Non-object context values rejected with InvalidDataFormat error
- Context persists across executions (same pattern as set_input)
- Null alias registry documented as caller responsibility
- Rc::try_unwrap optimization avoids unnecessary Program clone
- Feature-gated with #[cfg(feature = "azure_policy")]

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@anakrish anakrish requested a review from Copilot May 11, 2026 17:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR adds Azure Policy JSON compilation and evaluation support through the Rust FFI layer and exposes it via new C# bindings, enabling callers to compile/evaluate Azure Policy rules/definitions without translating to Rego.

Changes:

  • Added new FFI entry points to compile Azure Policy JSON (regorus_compile_azure_policy_rule, regorus_compile_azure_policy_definition) and to set VM context (regorus_rvm_set_context).
  • Added C# bindings (AzurePolicyCompiler, Rvm.SetContextJson) plus example usage and tests.
  • Bumped FFI/C# package versions to 0.10.1.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
bindings/ffi/src/rvm.rs Adds regorus_rvm_set_context for supplying ambient context JSON to the RVM.
bindings/ffi/src/compile.rs Adds Azure Policy JSON compile entry points plus Rust-side tests.
bindings/ffi/src/alias_registry.rs Exposes alias maps to the compiler via new wrapper methods.
bindings/ffi/Cargo.toml Bumps regorus-ffi version to 0.10.1.
bindings/csharp/TargetExampleApp/Program.cs Adds an Azure Policy JSON compilation demo.
bindings/csharp/Regorus/Rvm.cs Adds SetContextJson wrapper over the new FFI entry point.
bindings/csharp/Regorus/Program.cs Makes Program constructor internal for internal factory usage.
bindings/csharp/Regorus/NativeMethods.cs Adds new P/Invoke signatures for Azure Policy compile + context APIs.
bindings/csharp/Regorus/AzurePolicyCompiler.cs Adds a C# helper to compile JSON policy rules/definitions into RVM programs.
bindings/csharp/Regorus.Tests/AzurePolicyCompilerTests.cs Adds MSTest coverage for compilation + evaluation + context behavior.
bindings/csharp/README.md Documents Azure Policy JSON evaluation workflow in C#.
bindings/csharp/Directory.Packages.props Bumps C# package version to 0.10.1.

Comment on lines +186 to +187
[DllImport(LibraryName, EntryPoint = "regorus_rvm_set_context", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_rvm_set_context(RegorusRvm* vm, byte* context_json);
Comment on lines +501 to +514
/// <summary>
/// Compile an Azure Policy JSON policy rule into an RVM program.
/// </summary>
[DllImport(LibraryName, EntryPoint = "regorus_compile_azure_policy_rule", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_compile_azure_policy_rule(
RegorusAliasRegistry* registry, byte* policy_rule_json);

/// <summary>
/// Compile a full Azure Policy definition JSON into an RVM program.
/// </summary>
[DllImport(LibraryName, EntryPoint = "regorus_compile_azure_policy_definition", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_compile_azure_policy_definition(
RegorusAliasRegistry* registry, byte* policy_definition_json);

Comment on lines +509 to +513
/// Compile a full Azure Policy definition JSON into an RVM program.
/// </summary>
[DllImport(LibraryName, EntryPoint = "regorus_compile_azure_policy_definition", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern RegorusResult regorus_compile_azure_policy_definition(
RegorusAliasRegistry* registry, byte* policy_definition_json);
Comment thread bindings/ffi/src/rvm.rs
.map_err(|e| (RegorusStatus::Error, format!("VM lock failed: {e}")))?;
let context_value = Value::from_json_str(&from_c_str(context_json).map_err(|e| {
(
RegorusStatus::InvalidDataFormat,
Comment on lines +27 to +38
pub(crate) fn alias_map(
&self,
) -> alloc::collections::BTreeMap<alloc::string::String, alloc::string::String> {
self.registry.alias_map()
}

/// Return a clone of the alias-to-modifiable map for use by the compiler.
pub(crate) fn alias_modifiable_map(
&self,
) -> alloc::collections::BTreeMap<alloc::string::String, bool> {
self.registry.alias_modifiable_map()
}
…erialization

- AliasRegistry::alias_map() and alias_modifiable_map() now return
  Rc<BTreeMap> instead of cloning the entire map on each call.
  The Rc is cached internally and invalidated on mutation.

- Compiler stores Rc<BTreeMap> instead of owned BTreeMap, allowing
  multiple compilations to share alias data without cloning 73K+
  entries each time.

- Fix null array deserialization: az provider list sometimes emits
  null instead of [] for resource_types, aliases, paths, and
  api_versions fields. Added deserialize_null_as_empty_vec.

- Updated FFI layer and examples for new Rc-based API.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
@anakrish anakrish force-pushed the anakrish/azure-policy-json-ffi branch from 51b5b1b to 427ce6c Compare May 15, 2026 17:02
@anakrish
Copy link
Copy Markdown
Collaborator Author

anakrish commented May 15, 2026

@copilot Use the deep-review skill to review this PR.

Add Criterion-based Rust benchmark and BenchmarkDotNet C# benchmark
for comparing policy evaluation performance across engines.

Benchmarks cover compile, hot-eval, cold-eval, and normalized-eval
tiers across 12 Azure Policy definitions of varying complexity.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants