mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Add comprehensive documentation and GitHub Copilot configuration: - docs/knowledge/: 17 deep-dive knowledge files covering value semantics, RVM architecture, builtins, FFI boundary, feature composition, error handling migration, policy evaluation security, Rego semantics, interpreter/compiler architecture, Azure Policy/RBAC, engine API, time builtins, language extension guide, tooling architecture, causality/partial eval, Rego compiler, Azure Policy aliases, and telemetry/diagnostics - .github/agents/: 16 role-specific AI agent definitions (red-teamer, semantics-expert, architect, performance-engineer, test-engineer, verification-engineer, security-auditor, reliability-engineer, support-engineer, ci-engineer, refactorer, api-steward, program-manager, demo-engineer, dx-engineer, tech-lead) - .github/skills/: 6 workflow skill definitions (thorough-review, design-alternatives, add-builtin, opa-conformance, security-review, verification) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: anakrish <35780660+anakrish@users.noreply.github.com>
180 lines
5.8 KiB
Markdown
180 lines
5.8 KiB
Markdown
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
|
|
<!-- Licensed under the MIT License. -->
|
|
|
|
# Knowledge: Engine API
|
|
|
|
Deep knowledge about the public `Engine` API (`src/engine.rs`). Read this
|
|
before modifying the engine's public interface or evaluation flow.
|
|
|
|
## Engine Structure
|
|
|
|
```rust
|
|
pub struct Engine {
|
|
modules: Rc<Vec<Ref<Module>>>, // Loaded policy modules
|
|
interpreter: Interpreter, // Execution engine
|
|
prepared: bool, // Compilation state flag
|
|
rego_v1: bool, // Language version
|
|
execution_timer_config: Option<ExecutionTimerConfig>,
|
|
policy_length_config: PolicyLengthConfig, // File size limits
|
|
}
|
|
```
|
|
|
|
## Primary API Flow
|
|
|
|
### 1. Policy Loading
|
|
|
|
```rust
|
|
pub fn add_policy(&mut self, path: String, rego: String) -> Result<String>
|
|
pub fn add_policy_from_file(&mut self, path: impl AsRef<Path>) -> Result<String>
|
|
```
|
|
|
|
- Parses Rego source via Lexer → Parser → AST
|
|
- Returns the package name (e.g., `"data.test"`)
|
|
- Sets `prepared = false` to trigger recompilation on next eval
|
|
- Enforces `PolicyLengthConfig` limits
|
|
|
|
### 2. Data and Input
|
|
|
|
```rust
|
|
pub fn add_data(&mut self, data: Value) -> Result<()> // Merge into data document
|
|
pub fn add_data_json(&mut self, data: &str) -> Result<()>
|
|
pub fn set_input(&mut self, input: Value)
|
|
pub fn set_input_json(&mut self, input: &str) -> Result<()>
|
|
pub fn clear_data(&mut self)
|
|
```
|
|
|
|
`add_data()` merges into the existing data document. It requires the value
|
|
to be an object (checked). Conflict detection on merge.
|
|
|
|
### 3. Evaluation
|
|
|
|
| Method | Returns | Use Case |
|
|
|--------|---------|----------|
|
|
| `eval_rule(rule)` | `Value` | Direct rule evaluation (fast) |
|
|
| `eval_query(query, tracing)` | `QueryResults` | OPA-compatible with bindings |
|
|
| `eval_bool_query(query)` | `bool` | Boolean shortcut |
|
|
| `eval_allow_query()` | `bool` | Common deny-by-default pattern |
|
|
| `eval_modules(tracing)` | `Value` | Evaluate all loaded modules |
|
|
|
|
### 4. Compilation (for repeated evaluation)
|
|
|
|
```rust
|
|
pub fn compile_for_target(&mut self) -> Result<CompiledPolicy>
|
|
pub fn compile_with_entrypoint(&mut self, rule: &Rc<str>) -> Result<CompiledPolicy>
|
|
```
|
|
|
|
Returns `CompiledPolicy` — an immutable, precompiled artifact that can be
|
|
evaluated many times with different inputs:
|
|
|
|
```rust
|
|
let compiled = engine.compile_for_target()?;
|
|
// Later, potentially in a different thread:
|
|
let result = compiled.eval_with_input(input)?;
|
|
```
|
|
|
|
### 5. Configuration
|
|
|
|
```rust
|
|
pub fn set_rego_v0(&mut self, enabled: bool) // Language version
|
|
pub fn set_execution_timer_config(config) // Timeout limits
|
|
pub fn set_policy_length_config(config) // File size limits
|
|
pub fn set_strict_builtin_errors(b: bool) // Error vs Undefined for type mismatches
|
|
pub fn add_extension(name, arity, func) // Custom functions
|
|
```
|
|
|
|
## CompiledPolicy
|
|
|
|
```rust
|
|
pub struct CompiledPolicy {
|
|
inner: Rc<CompiledPolicyData>,
|
|
}
|
|
|
|
struct CompiledPolicyData {
|
|
modules: Rc<Vec<Ref<Module>>>,
|
|
schedule: Option<Rc<Schedule>>, // Pre-computed statement order
|
|
rules: Map<String, Vec<Ref<Rule>>>, // Rule path → rules
|
|
default_rules: Map<String, Vec<...>>, // Default rules
|
|
imports: BTreeMap<String, Ref<Expr>>,
|
|
functions: FunctionTable, // User-defined functions
|
|
rule_paths: Set<String>,
|
|
loop_hoisting_table: HoistedLoopsLookup, // Pre-computed loop info
|
|
data: Option<Value>, // Preloaded data
|
|
strict_builtin_errors: bool,
|
|
extensions: Map<String, (u8, Rc<Box<dyn Extension>>)>,
|
|
}
|
|
```
|
|
|
|
**Benefits of CompiledPolicy:**
|
|
- Schedule, loop hoisting, and function table pre-computed once
|
|
- Can be cloned cheaply (Rc internals)
|
|
- Supports repeated evaluation with different inputs
|
|
- Thread-safe when using `arc` feature
|
|
|
|
## Internal Evaluation Flow
|
|
|
|
When `eval_rule()` is called:
|
|
|
|
1. **Preparation** (if not `prepared`):
|
|
- Gather all functions from modules → `FunctionTable`
|
|
- Run scheduler on all queries → `Schedule`
|
|
- Run loop hoister → `HoistedLoopsLookup`
|
|
- Build `CompiledPolicyData`
|
|
- Set `prepared = true`
|
|
|
|
2. **Interpreter setup**:
|
|
- Set data and input on interpreter
|
|
- Set current module context
|
|
|
|
3. **Evaluation**:
|
|
- Find rule in `compiled_policy.rules`
|
|
- Call `interpreter.eval_rule()`
|
|
- Return result
|
|
|
|
## Multiple Module Management
|
|
|
|
- Modules stored as `Rc<Vec<Ref<Module>>>`
|
|
- Each module declares a package namespace (e.g., `package auth`)
|
|
- Rules qualified by package path: `data.auth.allow`
|
|
- Imports resolve cross-module references
|
|
- Functions tracked globally in `FunctionTable`
|
|
|
|
## Extensions API
|
|
|
|
Custom functions can be registered at runtime:
|
|
|
|
```rust
|
|
engine.add_extension(
|
|
"custom.check".to_string(),
|
|
2, // arity
|
|
Rc::new(Box::new(|args| -> Result<Value> {
|
|
// implementation
|
|
})),
|
|
)?;
|
|
```
|
|
|
|
Extensions are available to Rego policies as builtin functions.
|
|
|
|
## Metadata Access
|
|
|
|
```rust
|
|
pub fn get_packages(&self) -> Result<Vec<String>> // Package names
|
|
pub fn get_policies(&self) -> Result<Vec<Source>> // Policy sources
|
|
pub fn get_policies_as_json(&self) -> Result<String> // JSON representation
|
|
pub fn get_coverage_report(&self) -> Result<Report> // Code coverage
|
|
```
|
|
|
|
## Key Design Decisions
|
|
|
|
1. **Lazy compilation** — policies aren't compiled until first evaluation.
|
|
`prepared` flag tracks whether compilation is needed.
|
|
|
|
2. **Data merging** — `add_data()` merges, doesn't replace. Multiple data
|
|
sources accumulate into the data document.
|
|
|
|
3. **Input replacement** — `set_input()` replaces, doesn't merge. Each
|
|
evaluation gets a fresh input.
|
|
|
|
4. **Clone semantics** — `Engine::clone()` clones all persistent state
|
|
(policies, data, configuration) but resets runtime state (processed
|
|
rules, caches). The clone is ready for independent evaluation.
|