Policy Compilation
To evaluate policy modules they need to be compiled into WASM.
You can compile them manually with opa build -t wasm ... command or ask OpaDotNet do that for you.
OpaDotNet provides two options for policy compilation:
OpaDotNet.Compilation.Cli- wrapper overopaCLI tool.OpaDotNet.Compilation.Interop- wrapper over OPA SDK.
Which one you should be using?
Use OpaDotNet.Compilation.Cli if you have opa CLI tool available or you need functionality besides compilation (running tests, syntax checking etc.). Suitable for web applications and/or applications running in Docker containers. See Cli Compiler for more details.
Use OpaDotNet.Compilation.Interop if you need compilation only and want to avoid having external dependencies. Suitable for libraries, console application etc. See SDK Interop Compiler for more details.
If you sign your bundles to protect against tampering, see Bundle Signature Validation for how to verify signatures when loading a bundle.
Building bundles with BundleWriter
Both compilers accept a bundle directory path or a bundle as a Stream (CompileBundleAsync). If your policy
sources and data don't live on disk as a directory - e.g. they come from a database, embedded resources, or are
generated at runtime - use BundleWriter to assemble a bundle
Stream in memory instead of writing files to a temp folder first.
var policySource = """
package example
default hello = false
hello {
x := input.message
x == data.world
}
""";
var dataSource = """{ "world": "world" }""";
using var bundleStream = new MemoryStream();
// Assemble policy source and data files into a bundle, entirely in memory.
await using (var writer = new BundleWriter(bundleStream))
{
writer.WriteEntry(policySource, "policy.rego");
writer.WriteEntry(dataSource, "data.json");
}
bundleStream.Seek(0, SeekOrigin.Begin);
// The bundle still needs to be compiled to wasm before it can be evaluated.
var compiler = new RegoCliCompiler();
var policy = await compiler.CompileBundleAsync(
bundleStream,
new()
{
Entrypoints = ["example/hello"],
},
cancellationToken
);
using var engine = OpaBundleEvaluatorFactory.Create(policy);
Other things BundleWriter can do:
WriteFile- add the contents of an existing file on disk as a bundle entry.WriteManifest/ themanifestconstructor parameter - add bundle manifest (.manifest: roots, revision, metadata) into the bundle.WriteBundle- merge the entries of another bundle with sources into this one, useful for combining several policies into a single bundle.FromDirectory- create aBundleWriterpre-populated from a source directory, optionally excluding files matching glob patterns.MergeCapabilities- a static helper that merges twocapabilities.jsonfiles (e.g. built-in capabilities plus your own custom builtins) into one.
Note
BundleWriter strips a UTF-8 byte-order-mark from entries content if present - opa build fails to parse .rego
files that have one.
BundleWriter writes a bundle of sources (.rego/.json/.yaml), not compiled wasm - you still need to run it
through RegoCliCompiler or RegoInteropCompiler to get an evaluable policy.wasm bundle.