feat: Complete target system with C# bindings and resource inference (#458)

* feat: Add Schema Registry and Validation Framework

This commit introduces a comprehensive schema registry and validation framework, providing schema-based validation of resources and policy effects.

- Thread-safe, in-memory registry for schema storage and management
- Global registry patterns for effects and resources
- Concurrent access with proper error handling
- Unicode schema names support

- JSON Schema-compliant validation for all primitive types
- Advanced constraint validation (patterns, ranges, length limits)
- Discriminated union support with anyOf schemas
- Detailed error reporting with nested validation paths
- Discriminated subobject validation for polymorphic schemas

- **Registry Tests**: All registry operations
- **Effect Tests**: Policy effect validation
- **Resource Tests**: Resource validation
- **Validation Tests**: Core validation engine
- Thread-safety, error handling, integration scenarios, edge cases

- **Dependencies**: dashmap, once_cell, regex
- **Thread Safety**: Minimal locking with Rc<Schema> sharing
- **Error Types**: TypeMismatch, OutOfRange, PatternMismatch, etc.

- Complete schema registry and validation subsystem
- Comprehensive test coverage
- Foundation for policy validation in Regorus

Benchmarks:

- Criterion benchmarks for basic types, effects and Azure resources
- Performance range: 3.22ns (string) to 34.74µs (Azure VM resource schema validation)
- String withs patterns validation: 30.2µs. Need to explore whether regex caching helps
  bring this down.
- Azure policy effects: 188ns-1.4µs

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

* feat: Complete target system with C# bindings and resource inference

- Add comprehensive target system with TargetRegistry and target-aware compilation
- Implement resource type inference from policy equality expressions
- Create modular C# bindings with separate wrapper classes for each concept
- Add thread-safe CompiledPolicy with reference counting for safe disposal
- Enhance FFI with detailed error propagation and target functionality
- Create TargetExampleApp demonstrating Azure Policy integration
- Add CI/CD pipeline testing for all C# applications
- Support target definitions with schema validation and resource selectors
- Implement PolicyModule struct and target-aware compilation methods
- Add comprehensive test coverage for target functionality

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>

---------

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2025-08-19 20:23:43 -05:00
committed by GitHub
parent 3c33d31d08
commit cc917ea75d
71 changed files with 10278 additions and 1000 deletions
+2 -3
View File
@@ -3,10 +3,9 @@
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
@@ -0,0 +1,80 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: basic string formatting with spaces
data: {}
modules:
- |
package test
test1 := sprintf("User %s from %s has access", ["alice", "engineering"])
test2 := sprintf("A %s B %s C", ["X", "Y"])
test3 := sprintf("No spaces%s%s", ["A", "B"])
test4 := sprintf("Single %s", ["word"])
test5 := sprintf("Start %s end", ["middle"])
query: data.test
want_result:
test1: "User alice from engineering has access"
test2: "A X B Y C"
test3: "No spacesAB"
test4: "Single word"
test5: "Start middle end"
- note: numeric formatting
data: {}
modules:
- |
package test
decimal := sprintf("Number: %d", [42])
float := sprintf("Float: %f", [3.14])
hex := sprintf("Hex: %x", [255])
octal := sprintf("Octal: %o", [64])
binary := sprintf("Binary: %b", [15])
query: data.test
want_result:
decimal: "Number: 42"
float: "Float: 3.14"
hex: "Hex: ff"
octal: "Octal: 0O100"
binary: "Binary: 1111"
- note: mixed types and escaping
data: {}
modules:
- |
package test
mixed := sprintf("String: %s, Number: %d, Percent: %%", ["hello", 123])
verbose := sprintf("Value: %v", [{"key": "value"}])
query: data.test
want_result:
mixed: "String: hello, Number: 123, Percent: %"
verbose: "Value: {\"key\": \"value\"}"
- note: width formatting
data: {}
modules:
- |
package test
padded := sprintf("Padded: %5d", [42])
zero_padded := sprintf("Zero padded: %05d", [42])
decimal_places := sprintf("Decimal: %.2f", [3.14159])
query: data.test
want_result:
padded: "Padded: 42"
zero_padded: "Zero padded: 00042"
decimal_places: "Decimal: 3.14"
- note: error cases
data: {}
modules:
- |
package test
# This should cause an error - missing argument
error_case := sprintf("Value: %s %d", ["only_one"])
query: data.test
error: "no argument specified for format verb 1"
@@ -0,0 +1,79 @@
cases:
- note: "Azure Policy Basic Allow Test"
data: {}
input:
type: "Microsoft.Storage/storageAccounts"
name: "mystorageaccount"
location: "East US"
kind: "StorageV2"
properties:
supportsHttpsTrafficOnly: true
minimumTlsVersion: "TLS1_2"
tags:
environment: "production"
modules:
- |
package azure.policy.allow
import rego.v1
__target__ := "target.tests.azure_policy"
default allow := false
allow if {
input.type == "Microsoft.Storage/storageAccounts"
input.properties.supportsHttpsTrafficOnly == true
}
query: data.azure.policy.allow.allow
want_result: true
- note: "Azure Policy Deny Test - HTTP Traffic"
data: {}
input:
type: "Microsoft.Storage/storageAccounts"
name: "insecurestorage"
location: "West US"
kind: "Storage"
properties:
supportsHttpsTrafficOnly: false
minimumTlsVersion: "TLS1_0"
modules:
- |
package azure.policy.deny
import rego.v1
__target__ := "target.tests.azure_policy"
deny := {
"message": "HTTPS traffic must be enabled"
} if {
input.type == "Microsoft.Storage/storageAccounts"
input.properties.supportsHttpsTrafficOnly == false
}
query: data.azure.policy.deny.deny
want_result:
message: "HTTPS traffic must be enabled"
- note: "Azure Policy Invalid Resource Type"
data: {}
input:
type: "Microsoft.UnknownService/unknownResource"
name: "test"
modules:
- |
package azure.policy.invalid
import rego.v1
__target__ := "target.tests.azure_policy"
default allow := false
allow if {
input.type == "Microsoft.Storage/storageAccounts"
input.properties.supportsHttpsTrafficOnly == true
}
query: data.azure.policy.invalid.allow
want_result: false
+682
View File
@@ -0,0 +1,682 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: "target/valid_target"
data: {}
input: {"name": "valid"}
modules:
- |
package test.allow
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
allow if {
input.name == "valid"
}
query: data.test.allow.allow
want_result: true
- note: "target/missing_assignment_operator"
data: {}
modules:
- |
package test.missing_assignment
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
query: data.test.missing_assignment.allow
want_result: "#undefined"
- note: "target/effect_validation_undefined_result"
data: {}
input: {"name": "invalid"}
modules:
- |
package test.undefined
import rego.v1
__target__ := "target.tests.sample_test_target"
# No default, rule doesn't match, so allow is undefined
allow if {
input.name == "valid"
}
query: data.test.undefined.allow
want_result: "#undefined"
- note: "target/target_resolution_timing"
data: {}
input: {"name": "valid"}
modules:
- |
package test
import rego.v1
__target__ "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
query: data.test.allow
error: "expected ':=' after __target__"
- note: "target/missing_string_literal"
data: {}
modules:
- |
package test
import rego.v1
__target__ := 123
allow if {
input.name == "valid"
}
query: data.test.allow
error: "expected string literal"
- note: "target/invalid_string_format"
data: {}
modules:
- |
package test
import rego.v1
__target__ := "unterminated string
allow if {
input.name == "valid"
}
query: data.test.allow
error: "unterminated string"
- note: "target/nonexistent_target"
data: {}
input: {"name": "valid"}
modules:
- |
package test
import rego.v1
__target__ := "nonexistent.target.name"
allow if {
input.name == "valid"
}
query: data.test.allow
error: "Target 'nonexistent.target.name' not found in registry"
- note: "target/target_before_imports"
data: {}
modules:
- |
package test
__target__ := "target.tests.sample_test_target"
import rego.v1
allow if {
input.name == "valid"
}
query: data.test.allow
error: "unexpected keyword `import`"
- note: "target/target_after_rule"
data: {}
input: {"name": "valid"}
modules:
- |
package test
import rego.v1
allow if {
input.name == "valid"
}
__target__ := "target.tests.sample_test_target"
query: data.test.allow
error: "__target__ must be defined before any rules"
- note: "target/multiple_modules_same_target"
data: {}
input: {"name": "valid"}
modules:
- |
package test.module1
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.module2
import rego.v1
__target__ := "target.tests.sample_test_target"
deny if {
input.name == "invalid"
}
query: data.test.module1.allow
error: "Modules with target 'target.tests.sample_test_target' have different packages: 'test.module1' and 'test.module2'"
- note: "target/multiple_modules_same_target_same_package"
data: {}
input: {"name": "valid"}
modules:
- |
package test.shared
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.shared
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "invalid"
}
query: data.test.shared.allow
want_result: true
- note: "target/multiple_modules_different_targets"
data: {}
input: {"name": "valid"}
modules:
- |
package test.module1
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.module2
import rego.v1
__target__ := "target.tests.azure_compute"
deny if {
input.name == "invalid"
}
query: data.test.module1.allow
error: "Multiple different targets specified: 'target.tests.sample_test_target' and 'target.tests.azure_compute'"
- note: "target/multiple_different_effects_same_package"
data: {}
input: {"name": "valid"}
modules:
- |
package test.multieffect
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
deny if {
input.name == "invalid"
}
query: data.test.multieffect.allow
error: "Multiple effects have rules defined for target 'target.tests.sample_test_target': allow, deny. Only one effect should have rules defined in package 'test.multieffect'"
- note: "target/no_effect_rules_defined"
data: {}
input: {"name": "valid"}
modules:
- |
package test.noeffects
import rego.v1
__target__ := "target.tests.sample_test_target"
helper_function(x) if {
x == "valid"
}
query: data.test.noeffects.helper_function("valid")
error: "Target 'target.tests.sample_test_target' requires a rule with name allow, deny or test_effect in package 'test.noeffects'"
- note: "target/valid_deny_effect"
data: {}
input: {"name": "invalid"}
modules:
- |
package test.deny
import rego.v1
__target__ := "target.tests.sample_test_target"
default deny := false
deny if {
input.name == "invalid"
}
query: data.test.deny.deny
want_result: true
- note: "target/valid_test_effect"
data: {}
input: {"level": "warning", "message": "test message"}
modules:
- |
package test.custom
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": input.level,
"message": input.message
} if {
input.level
input.message
}
query: data.test.custom.test_effect
want_result: {"level": "warning", "message": "test message"}
- note: "target/multiple_rules_same_effect_same_module"
data: {}
input: {"name": "valid", "role": "admin"}
modules:
- |
package test.multirules
import rego.v1
__target__ := "target.tests.sample_test_target"
# Multiple rules for the same effect in the same module
allow if {
input.name == "valid"
}
allow if {
input.role == "admin"
}
query: data.test.multirules.allow
want_result: true
- note: "target/multiple_rules_same_effect_different_modules"
data: {}
input: {"name": "valid", "role": "admin"}
modules:
- |
package test.distributed
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.distributed
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.role == "admin"
}
query: data.test.distributed.allow
want_result: true
- note: "target/effect_with_non_effect_rules_same_module"
data: {}
input: {"name": "valid"}
modules:
- |
package test.mixed
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
# Non-effect helper rule
is_admin if {
input.role == "admin"
}
# Another non-effect rule
helper_data := {"status": "active"}
query: data.test.mixed.allow
want_result: true
- note: "target/effect_with_non_effect_rules_different_modules"
data: {}
input: {"name": "valid", "role": "admin"}
modules:
- |
package test.separate
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.separate
import rego.v1
__target__ := "target.tests.sample_test_target"
# Non-effect helper rules in different module
is_admin if {
input.role == "admin"
}
user_data := {"type": "user", "active": true}
query: data.test.separate.allow
want_result: true
- note: "target/effect_subpath_should_fail"
data: {}
input: {"name": "valid"}
modules:
- |
package test.subpath
import rego.v1
__target__ := "target.tests.sample_test_target"
# This creates a rule at data.test.subpath.allow.nested.rule
# which is a subpath of the expected effect path data.test.subpath.allow
allow.nested.rule if {
input.name == "valid"
}
query: data.test.subpath.allow.nested.rule
error: "Target 'target.tests.sample_test_target' requires a rule with name allow, deny or test_effect in package 'test.subpath'"
- note: "target/multiple_subpath_rules_should_fail"
data: {}
input: {"name": "valid"}
modules:
- |
package test.multisubpath
import rego.v1
__target__ := "target.tests.sample_test_target"
# Multiple subpath rules under allow
allow.users.admin if {
input.name == "valid"
}
allow.users.guest if {
input.name == "guest"
}
query: data.test.multisubpath.allow.users.admin
error: "Target 'target.tests.sample_test_target' requires a rule with name allow, deny or test_effect in package 'test.multisubpath'"
- note: "target/effect_schema_validation_valid"
data: {}
input: {"name": "valid"}
modules:
- |
package test.schema_valid
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
query: data.test.schema_valid.allow
want_result: true
- note: "target/effect_schema_validation_invalid_type"
data: {}
input: {"name": "valid"}
modules:
- |
package test.schema_invalid
import rego.v1
__target__ := "target.tests.sample_test_target"
# test_effect schema expects object with string properties, but we return a string
test_effect := "invalid_string_instead_of_object" if {
input.name == "valid"
}
query: data.test.schema_invalid.test_effect
error: "Type mismatch"
- note: "target/effect_schema_validation_missing_required_field"
data: {}
input: {"name": "valid"}
modules:
- |
package test.schema_missing_field
import rego.v1
__target__ := "target.tests.sample_test_target"
# test_effect expects an object, but with invalid property types
test_effect := {
"level": 123, # should be string, not number
"message": "test message"
} if {
input.name == "valid"
}
query: data.test.schema_missing_field.test_effect
error: "Type mismatch"
- note: "target/effect_schema_validation_complex_object"
data: {}
input: {"name": "valid", "details": {"severity": "high", "category": "security"}}
modules:
- |
package test.schema_complex
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "error",
"message": "Security violation detected",
"details": input.details
} if {
input.name == "valid"
input.details.severity == "high"
}
query: data.test.schema_complex.test_effect
want_result: {"level": "error", "message": "Security violation detected", "details": {"severity": "high", "category": "security"}}
- note: "target/effect_schema_validation_enum_constraint"
data: {}
input: {"name": "valid"}
modules:
- |
package test.schema_enum
import rego.v1
__target__ := "target.tests.sample_test_target"
# test_effect requires an object, but we return an array instead
test_effect := ["invalid", "array", "instead", "of", "object"] if {
input.name == "valid"
}
query: data.test.schema_enum.test_effect
error: "Type mismatch"
- note: "target/multiple_targets_different_schemas"
data: {}
input: {"name": "valid"}
modules:
- |
package test.multi_target_a
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.multi_target_b
import rego.v1
__target__ := "target.tests.azure_compute"
deny if {
input.name == "invalid"
}
query: data.test.multi_target_a.allow
error: "Multiple different targets specified"
- note: "target/effect_validation_with_default_value"
data: {}
input: {"name": "valid"}
modules:
- |
package test.with_default
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
allow if {
input.name == "valid"
}
query: data.test.with_default.allow
want_result: true
- note: "target/effect_validation_undefined_result"
data: {}
input: {"name": "invalid"}
modules:
- |
package test.undefined
import rego.v1
__target__ := "target.tests.sample_test_target"
# No default, rule doesn't match, so allow is undefined
allow if {
input.name == "valid"
}
query: data.test.undefined.allow
want_result: "#undefined"
- note: "target/target_resolution_timing"
data: {}
input: {"name": "valid"}
modules:
- |
package test.timing
import rego.v1
__target__ := "target.tests.sample_test_target"
# Rule defined after target - should work due to proper timing
allow if {
input.name == "valid"
}
# Helper rule that's not an effect
helper := "test" if true
query: data.test.timing.allow
want_result: true
- note: "target/nested_package_structure"
data: {}
input: {"name": "valid"}
modules:
- |
package test.nested.deep.structures
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
query: data.test.nested.deep.structures.allow
want_result: true
- note: "target/package_validation_error_consistency"
data: {}
input: {"name": "valid"}
modules:
- |
package test.package_a
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.name == "valid"
}
- |
package test.package_b
import rego.v1
__target__ := "target.tests.sample_test_target"
deny if {
input.name == "invalid"
}
query: data.test.package_a.allow
error: "Modules with target 'target.tests.sample_test_target' have different packages: 'test.package_a' and 'test.package_b'"
+561
View File
@@ -0,0 +1,561 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
cases:
- note: "target/complex_nested_object_validation"
data: {}
input: {"user": {"name": "alice", "roles": ["admin", "user"], "metadata": {"department": "engineering", "level": 5}}}
modules:
- |
package policy.complex
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("User %s from %s has access", [input.user.name, input.user.metadata.department]),
"details": {
"user_roles": input.user.roles,
"access_level": input.user.metadata.level,
"timestamp": "2025-08-14T10:00:00Z"
}
} if {
"admin" in input.user.roles
input.user.metadata.level >= 3
}
query: data.policy.complex.test_effect
want_result: {
"details": {
"access_level": 5,
"timestamp": "2025-08-14T10:00:00Z",
"user_roles": ["admin", "user"]
},
"level": "info",
"message": "User alice from engineering has access"
}
- note: "target/complex_conditional_logic_with_multiple_rules"
data: {}
input: {"resource": {"type": "document", "classification": "confidential", "owner": "alice"}, "requester": {"id": "bob", "clearance": "secret"}}
modules:
- |
package policy.access_control
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Multiple complex rules for the same effect
allow if {
input.resource.classification == "public"
}
allow if {
input.resource.owner == input.requester.id
}
allow if {
input.resource.classification == "confidential"
input.requester.clearance in ["secret", "top_secret"]
count([role | role := input.requester.roles[_]; role == "analyst"]) > 0
}
allow if {
input.resource.type == "document"
input.requester.clearance == "top_secret"
}
query: data.policy.access_control.allow
want_result: false
- note: "target/complex_data_manipulation_with_comprehensions"
data: {
"users": [
{"id": "u1", "name": "alice", "department": "eng", "salary": 100000},
{"id": "u2", "name": "bob", "department": "sales", "salary": 80000},
{"id": "u3", "name": "charlie", "department": "eng", "salary": 120000}
]
}
input: {"department_filter": "eng", "min_salary": 90000}
modules:
- |
package policy.hr_analysis
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("Found %d qualified users", [count(qualified_users)]),
"details": {
"qualified_users": qualified_users,
"avg_salary": avg_salary,
"total_budget": total_budget
}
} if {
count(qualified_users) > 0
}
qualified_users := [user |
user := data.users[_]
user.department == input.department_filter
user.salary >= input.min_salary
]
# Extract total_budget calculation to avoid scheduling error
total_budget := v if {
count(qualified_users) > 0
v := sum([salary |
true
user := qualified_users[_]
salary := user.salary
])
}
# Extract avg_salary calculation to avoid scheduling error
avg_salary := v if {
count(qualified_users) > 0
v := sum([salary |
true
user := qualified_users[_]
salary := user.salary
]) / count(qualified_users)
}
query: data.policy.hr_analysis.test_effect
want_result: {
"level": "info",
"message": "Found 2 qualified users",
"details": {
"qualified_users": [
{"id": "u1", "name": "alice", "department": "eng", "salary": 100000},
{"id": "u3", "name": "charlie", "department": "eng", "salary": 120000}
],
"avg_salary": 110000,
"total_budget": 220000
}
}
- note: "target/corner_case_empty_collections"
data: {"empty_array": [], "empty_object": {}}
input: {"filters": []}
modules:
- |
package policy.empty_collections
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
count(data.empty_array) == 0
count(object.keys(data.empty_object)) == 0
count(input.filters) == 0
}
query: data.policy.empty_collections.allow
want_result: true
- note: "target/corner_case_null_and_undefined_handling"
data: {"nullable_field": null}
input: {"optional_field": null}
modules:
- |
package policy.null_handling
import rego.v1
__target__ := "target.tests.sample_test_target"
default test_effect := {}
test_effect := {
"level": "warning",
"message": "Handling null values correctly"
} if {
data.nullable_field == null
input.optional_field == null
# Check that missing_field is undefined by ensuring it's not present
not "missing_field" in object.keys(data)
}
query: data.policy.null_handling.test_effect
want_result: {
"level": "warning",
"message": "Handling null values correctly"
}
- note: "target/corner_case_deeply_nested_structures"
data: {}
input: {
"request": {
"metadata": {
"auth": {
"user": {
"profile": {
"permissions": {
"read": ["doc1", "doc2"],
"write": ["doc1"]
}
}
}
}
}
}
}
modules:
- |
package policy.deep_nesting
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
permissions := input.request.metadata.auth.user.profile.permissions
"doc1" in permissions.read
"doc1" in permissions.write
}
query: data.policy.deep_nesting.allow
want_result: true
- note: "target/corner_case_unicode_and_special_characters"
data: {}
input: {
"user": "測試用戶",
"message": "Hello, 世界! 🌍",
"special_chars": "!@#$%^&*()_+-=[]{}|;':\",./<>?"
}
modules:
- |
package policy.unicode_handling
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("Processing for user: %s", [input.user])
} if {
contains(input.message, "世界")
startswith(input.special_chars, "!")
}
query: data.policy.unicode_handling.test_effect
want_result: {
"level": "info",
"message": "Processing for user: 測試用戶"
}
- note: "target/corner_case_large_numbers_and_precision"
data: {}
input: {
"large_int": 9223372036854775807,
"small_float": 0.000000000001,
"large_float": 1.7976931348623157e+308
}
modules:
- |
package policy.numeric_precision
import rego.v1
__target__ := "target.tests.sample_test_target"
allow if {
input.large_int > 9000000000000000000
input.small_float < 0.001
input.large_float > 1e100
}
query: data.policy.numeric_precision.allow
want_result: true
- note: "target/corner_case_circular_references_in_data"
data: {
"users": {
"alice": {"id": "alice", "manager": "bob"},
"bob": {"id": "bob", "manager": "charlie"},
"charlie": {"id": "charlie", "manager": "alice"}
}
}
input: {"check_user": "alice"}
modules:
- |
package policy.circular_refs
import rego.v1
__target__ := "target.tests.sample_test_target"
# Detect circular management chain
deny if {
has_circular_management(input.check_user, set())
}
has_circular_management(user_id, visited) if {
user_id in visited
}
has_circular_management(user_id, visited) if {
not user_id in visited
manager := data.users[user_id].manager
manager != null
has_circular_management(manager, visited | {user_id})
}
query: data.policy.circular_refs.deny
want_result: true
- note: "target/complex_schema_validation_failure_detailed"
data: {}
input: {"name": "test"}
modules:
- |
package policy.schema_failure
import rego.v1
__target__ := "target.tests.sample_test_target"
# This should fail schema validation - wrong structure entirely
test_effect := {
"invalid_field": "should_not_exist",
"level": 123, # should be string
"message": ["array", "instead", "of", "string"], # should be string
"extra_nested": {
"deep": {
"structure": "not_allowed"
}
}
} if {
input.name == "test"
}
query: data.policy.schema_failure.test_effect
error: "Type mismatch"
- note: "target/complex_multiple_modules_with_helper_functions"
data: {}
input: {"operation": "delete", "resource_id": "sensitive_doc", "user_role": "admin"}
modules:
- |
package policy.authorization
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Reference helper functions from the same package
allow if {
is_admin(input.user_role)
is_allowed_operation(input.operation)
not is_sensitive_resource(input.resource_id)
}
- |
package policy.authorization
import rego.v1
__target__ := "target.tests.sample_test_target"
is_admin(role) if {
role == "admin"
}
is_allowed_operation(op) if {
op in ["read", "write", "delete"]
}
is_sensitive_resource(resource_id) if {
startswith(resource_id, "sensitive_")
}
query: data.policy.authorization.allow
want_result: false
- note: "target/corner_case_very_long_strings"
data: {}
input: {
"long_string": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo."
}
modules:
- |
package policy.long_strings
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("String length: %d characters", [count(input.long_string)])
} if {
count(input.long_string) > 500
contains(input.long_string, "Lorem ipsum")
}
query: data.policy.long_strings.test_effect
want_result: {
"level": "info",
"message": "String length: 661 characters"
}
- note: "target/complex_regex_pattern_matching"
data: {}
input: {
"emails": [
"valid@example.com",
"also.valid+tag@domain.co.uk",
"invalid.email",
"another@valid-domain.org"
]
}
modules:
- |
package policy.email_validation
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("Validated %d emails, %d valid", [count(input.emails), count(valid_emails)])
} if {
count(valid_emails) > 0
}
valid_emails := [email |
email := input.emails[_]
regex.match(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`, email)
]
query: data.policy.email_validation.test_effect
want_result: {
"level": "info",
"message": "Validated 4 emails, 3 valid"
}
- note: "target/corner_case_recursive_data_structures"
data: {
"filesystem": {
"root": {
"type": "directory",
"children": {
"home": {
"type": "directory",
"children": {
"user": {
"type": "directory",
"children": {
"document.txt": {"type": "file", "size": 1024}
}
}
}
},
"etc": {
"type": "directory",
"children": {
"config.ini": {"type": "file", "size": 512}
}
}
}
}
}
}
input: {"search_type": "file"}
modules:
- |
package policy.filesystem
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": sprintf("Found %d files", [count(all_files)])
} if {
count(all_files) > 0
}
all_files[path] := file if {
walk(data.filesystem, [path, file])
file.type == input.search_type
}
query: data.policy.filesystem.test_effect
want_result: {
"level": "info",
"message": "Found 2 files"
}
- note: "target/complex_error_propagation_and_recovery"
data: {}
input: {"values": [1, 2, 0, 4, 5]}
modules:
- |
package policy.error_handling
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "warning",
"message": sprintf("Division results: %v", [safe_divisions])
} if {
count(safe_divisions) > 0
}
safe_divisions := [result |
value := input.values[i]
value != 0 # Skip zero values to avoid division by zero
result := 100 / value
]
query: data.policy.error_handling.test_effect
want_result: {
"level": "warning",
"message": "Division results: [100, 50, 25, 20]"
}
- note: "target/corner_case_edge_conditions_with_sets"
data: {}
input: {
"set1": ["a", "b", "c"],
"set2": ["b", "c", "d"],
"set3": ["c", "d", "e"]
}
modules:
- |
package policy.set_operations
import rego.v1
__target__ := "target.tests.sample_test_target"
test_effect := {
"level": "info",
"message": "Set operations completed",
"details": {
"intersection_all": intersection_all,
"union_all": union_all,
"symmetric_diff": symmetric_diff
}
} if {
count(intersection_all) > 0
}
s1 := {x | x := input.set1[_]}
s2 := {x | x := input.set2[_]}
s3 := {x | x := input.set3[_]}
intersection_all := s1 & s2 & s3
union_all := s1 | s2 | s3
symmetric_diff := (s1 | s2) - (s1 & s2)
query: data.policy.set_operations.test_effect
want_result: {
"level": "info",
"message": "Set operations completed",
"details": {
"intersection_all": { "set!": ["c"] },
"union_all": { "set!": ["a", "b", "c", "d", "e"] },
"symmetric_diff": { "set!": ["a", "d"] }
}
}
@@ -0,0 +1,47 @@
{
"name": "target.tests.azure_compute",
"description": "Azure compute resources target for testing",
"version": "1.0.0",
"resource_schema_selector": "type",
"resource_schemas": [
{
"type": "object",
"properties": {
"type": { "const": "Microsoft.Compute/virtualMachines" },
"name": { "type": "string" },
"location": { "type": "string" },
"properties": {
"type": "object",
"properties": {
"vmSize": { "type": "string" },
"storageProfile": {
"type": "object",
"properties": {
"imageReference": {
"type": "object",
"properties": {
"publisher": { "type": "string" },
"offer": { "type": "string" },
"sku": { "type": "string" }
}
}
}
}
}
}
},
"required": ["type", "name", "location"]
}
],
"effects": {
"allow": { "type": "boolean" },
"deny": { "type": "boolean" },
"audit": {
"type": "object",
"properties": {
"level": { "enum": ["info", "warning", "error"] },
"message": { "type": "string" }
}
}
}
}
@@ -0,0 +1,125 @@
{
"name": "target.tests.azure_policy",
"description": "Azure Policy target for comprehensive policy evaluation testing",
"version": "1.0.0",
"resource_schema_selector": "type",
"resource_schemas": [
{
"type": "object",
"properties": {
"type": { "const": "Microsoft.Resources/subscriptions" },
"subscriptionId": { "type": "string" },
"tenantId": { "type": "string" },
"displayName": { "type": "string" }
},
"required": ["type", "subscriptionId"]
},
{
"type": "object",
"properties": {
"type": { "const": "Microsoft.Storage/storageAccounts" },
"name": { "type": "string" },
"location": { "type": "string" },
"kind": { "enum": ["Storage", "StorageV2", "BlobStorage", "FileStorage", "BlockBlobStorage"] },
"properties": {
"type": "object",
"properties": {
"supportsHttpsTrafficOnly": { "type": "boolean" },
"minimumTlsVersion": { "enum": ["TLS1_0", "TLS1_1", "TLS1_2"] },
"allowBlobPublicAccess": { "type": "boolean" },
"encryption": {
"type": "object",
"properties": {
"services": {
"type": "object",
"properties": {
"blob": { "type": "object", "properties": { "enabled": { "type": "boolean" } } },
"file": { "type": "object", "properties": { "enabled": { "type": "boolean" } } }
}
}
}
}
}
},
"tags": { "type": "object" }
},
"required": ["type", "name", "location"]
},
{
"type": "object",
"properties": {
"type": { "const": "Microsoft.Network/networkSecurityGroups" },
"name": { "type": "string" },
"location": { "type": "string" },
"properties": {
"type": "object",
"properties": {
"securityRules": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"properties": {
"type": "object",
"properties": {
"direction": { "enum": ["Inbound", "Outbound"] },
"access": { "enum": ["Allow", "Deny"] },
"protocol": { "enum": ["Tcp", "Udp", "*"] },
"sourcePortRange": { "type": "string" },
"destinationPortRange": { "type": "string" },
"sourceAddressPrefix": { "type": "string" },
"destinationAddressPrefix": { "type": "string" },
"priority": { "type": "integer", "minimum": 100, "maximum": 4096 }
}
}
}
}
}
}
}
},
"required": ["type", "name", "location"]
}
],
"effects": {
"allow": { "type": "boolean" },
"deny": {
"type": "object",
"properties": {
"message": { "type": "string" }
}
},
"audit": {
"type": "object",
"properties": {
"level": { "enum": ["info", "warning", "error"] },
"message": { "type": "string" },
"complianceState": { "enum": ["Compliant", "NonCompliant", "Unknown"] }
}
},
"modify": {
"type": "object",
"properties": {
"operations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"operation": { "enum": ["add", "replace", "remove"] },
"field": { "type": "string" },
"value": { "type": "any" }
}
}
}
}
},
"deployIfNotExists": {
"type": "object",
"properties": {
"template": { "type": "object" },
"parameters": { "type": "object" }
}
}
}
}
@@ -0,0 +1,195 @@
{
"name": "target.tests.complex_target",
"description": "A complex target for testing advanced features including discriminated unions",
"version": "2.0.0",
"resource_schema_selector": "resourceType",
"resource_schemas": [
{
"type": "object",
"properties": {
"name": { "type": "string" },
"resourceType": { "const": "compute" },
"spec": {
"type": "object",
"properties": {
"cpu": { "type": "integer", "minimum": 1, "maximum": 64 },
"memory": { "type": "string", "pattern": "^[0-9]+[GM]i$" }
},
"required": ["cpu", "memory"]
}
},
"required": ["name", "resourceType", "spec"]
},
{
"type": "object",
"properties": {
"name": { "type": "string" },
"resourceType": { "const": "storage" },
"spec": {
"type": "object",
"properties": {
"size": { "type": "string", "pattern": "^[0-9]+[GTM]i$" },
"type": { "enum": ["ssd", "hdd", "nvme"] }
},
"required": ["size", "type"]
}
},
"required": ["name", "resourceType", "spec"]
},
{
"type": "object",
"properties": {
"name": { "type": "string" },
"resourceType": { "type": "string" },
"spec": { "type": "object" }
},
"required": ["name"],
"additionalProperties": true
}
],
"effects": {
"allow": { "type": "boolean" },
"deny": { "type": "boolean" },
"audit": {
"type": "object",
"properties": {
"action": { "type": "string" },
"severity": { "enum": ["low", "medium", "high", "critical"] },
"details": {
"type": "object",
"properties": {
"eventType": { "type": "string" }
},
"required": ["eventType"],
"allOf": [
{
"if": {
"properties": {
"eventType": { "const": "access" }
}
},
"then": {
"properties": {
"user": { "type": "string" },
"resource": { "type": "string" },
"timestamp": { "type": "string" }
},
"required": ["user", "resource", "timestamp"]
}
},
{
"if": {
"properties": {
"eventType": { "const": "modification" }
}
},
"then": {
"properties": {
"user": { "type": "string" },
"resource": { "type": "string" },
"changes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field": { "type": "string" },
"oldValue": { "type": "any" },
"newValue": { "type": "any" }
},
"required": ["field", "oldValue", "newValue"]
}
}
},
"required": ["user", "resource", "changes"]
}
},
{
"if": {
"properties": {
"eventType": { "const": "security" }
}
},
"then": {
"properties": {
"threatLevel": { "enum": ["low", "medium", "high"] },
"source": { "type": "string" },
"indicators": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["threatLevel", "source", "indicators"]
}
}
]
}
},
"required": ["action", "severity", "details"]
},
"remediate": {
"type": "object",
"properties": {
"actionType": { "type": "string" },
"config": {
"type": "object",
"properties": {
"operation": { "type": "string" }
},
"required": ["operation"],
"allOf": [
{
"if": {
"properties": {
"operation": { "const": "quarantine" }
}
},
"then": {
"properties": {
"duration": { "type": "string", "pattern": "^[0-9]+[hmd]$" },
"reason": { "type": "string" }
},
"required": ["duration", "reason"]
}
},
{
"if": {
"properties": {
"operation": { "const": "scale" }
}
},
"then": {
"properties": {
"targetSize": { "type": "integer", "minimum": 0, "maximum": 100 },
"metric": { "enum": ["cpu", "memory", "requests"] }
},
"required": ["targetSize", "metric"]
}
},
{
"if": {
"properties": {
"operation": { "const": "replace" }
}
},
"then": {
"properties": {
"newResource": {
"type": "object",
"properties": {
"type": { "type": "string" },
"spec": { "type": "object" }
},
"required": ["type", "spec"]
},
"preserveData": { "type": "boolean" }
},
"required": ["newResource", "preserveData"]
}
}
]
}
},
"required": ["actionType", "config"]
}
}
}
@@ -0,0 +1,189 @@
{
"name": "target.tests.msgraph",
"description": "Microsoft Graph API target for identity and access management testing",
"version": "1.0.0",
"resource_schema_selector": "@odata.type",
"resource_schemas": [
{
"type": "object",
"properties": {
"@odata.type": { "const": "#microsoft.graph.user" },
"id": { "type": "string" },
"userPrincipalName": { "type": "string" },
"displayName": { "type": "string" },
"givenName": { "type": "string" },
"surname": { "type": "string" },
"mail": { "type": "string" },
"jobTitle": { "type": "string" },
"department": { "type": "string" },
"accountEnabled": { "type": "boolean" },
"userType": { "enum": ["Member", "Guest"] },
"assignedLicenses": {
"type": "array",
"items": {
"type": "object",
"properties": {
"skuId": { "type": "string" },
"disabledPlans": { "type": "array", "items": { "type": "string" } }
}
}
},
"signInActivity": {
"type": "object",
"properties": {
"lastSignInDateTime": { "type": "string" },
"lastNonInteractiveSignInDateTime": { "type": "string" }
}
}
},
"required": ["@odata.type", "id", "userPrincipalName"]
},
{
"type": "object",
"properties": {
"@odata.type": { "const": "#microsoft.graph.group" },
"id": { "type": "string" },
"displayName": { "type": "string" },
"description": { "type": "string" },
"groupTypes": { "type": "array", "items": { "type": "string" } },
"securityEnabled": { "type": "boolean" },
"mailEnabled": { "type": "boolean" },
"mail": { "type": "string" },
"visibility": { "enum": ["Public", "Private", "HiddenMembership"] },
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"@odata.type": { "type": "string" }
}
}
}
},
"required": ["@odata.type", "id", "displayName"]
},
{
"type": "object",
"properties": {
"@odata.type": { "const": "#microsoft.graph.application" },
"id": { "type": "string" },
"appId": { "type": "string" },
"displayName": { "type": "string" },
"publisherDomain": { "type": "string" },
"signInAudience": { "enum": ["AzureADMyOrg", "AzureADMultipleOrgs", "AzureADandPersonalMicrosoftAccount", "PersonalMicrosoftAccount"] },
"requiredResourceAccess": {
"type": "array",
"items": {
"type": "object",
"properties": {
"resourceAppId": { "type": "string" },
"resourceAccess": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"type": { "enum": ["Scope", "Role"] }
}
}
}
}
}
},
"web": {
"type": "object",
"properties": {
"redirectUris": { "type": "array", "items": { "type": "string" } },
"implicitGrantSettings": {
"type": "object",
"properties": {
"enableAccessTokenIssuance": { "type": "boolean" },
"enableIdTokenIssuance": { "type": "boolean" }
}
}
}
}
},
"required": ["@odata.type", "id", "appId", "displayName"]
},
{
"type": "object",
"properties": {
"@odata.type": { "const": "#microsoft.graph.conditionalAccessPolicy" },
"id": { "type": "string" },
"displayName": { "type": "string" },
"state": { "enum": ["enabled", "disabled", "enabledForReportingButNotEnforced"] },
"conditions": {
"type": "object",
"properties": {
"users": {
"type": "object",
"properties": {
"includeUsers": { "type": "array", "items": { "type": "string" } },
"excludeUsers": { "type": "array", "items": { "type": "string" } },
"includeGroups": { "type": "array", "items": { "type": "string" } },
"excludeGroups": { "type": "array", "items": { "type": "string" } }
}
},
"applications": {
"type": "object",
"properties": {
"includeApplications": { "type": "array", "items": { "type": "string" } },
"excludeApplications": { "type": "array", "items": { "type": "string" } }
}
},
"locations": {
"type": "object",
"properties": {
"includeLocations": { "type": "array", "items": { "type": "string" } },
"excludeLocations": { "type": "array", "items": { "type": "string" } }
}
},
"riskLevels": { "type": "array", "items": { "enum": ["low", "medium", "high", "none"] } }
}
},
"grantControls": {
"type": "object",
"properties": {
"operator": { "enum": ["AND", "OR"] },
"builtInControls": { "type": "array", "items": { "enum": ["block", "mfa", "compliantDevice", "domainJoinedDevice", "approvedApplication", "compliantApplication"] } }
}
}
},
"required": ["@odata.type", "id", "displayName", "state"]
}
],
"effects": {
"allow": { "type": "boolean" },
"block": {
"type": "object",
"properties": {
"reason": { "type": "string" },
"blockType": { "enum": ["signin", "access", "registration"] }
}
},
"requireMfa": {
"type": "object",
"properties": {
"methods": { "type": "array", "items": { "enum": ["sms", "voice", "app", "oath"] } }
}
},
"audit": {
"type": "object",
"properties": {
"level": { "enum": ["info", "warning", "error"] },
"message": { "type": "string" },
"category": { "enum": ["signin", "audit", "risk", "provisioning"] }
}
},
"remediate": {
"type": "object",
"properties": {
"action": { "enum": ["disable", "enable", "reset", "notify"] },
"target": { "type": "string" },
"parameters": { "type": "object" }
}
}
}
}
@@ -0,0 +1,21 @@
{
"name": "target.tests.no_default_schema_target",
"description": "A target without a default schema for testing missing default schema error",
"version": "1.0.0",
"resource_schema_selector": "type",
"resource_schemas": [
{
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "const": "specific_resource_type" },
"value": { "type": "string" }
},
"required": ["name", "type"]
}
],
"effects": {
"allow": { "type": "boolean" },
"deny": { "type": "boolean" }
}
}
@@ -0,0 +1,38 @@
{
"name": "target.tests.sample_test_target",
"description": "A sample target for testing target loading functionality",
"version": "1.0.0",
"resource_schema_selector": "type",
"resource_schemas": [
{
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "const": "test_resource" },
"value": { "type": "string" }
},
"required": ["name", "type"]
},
{
"type": "object",
"properties": {
"name": { "type": "string" },
"type": { "type": "string" },
"value": { "type": "string" }
},
"required": ["name"],
"additionalProperties": true
}
],
"effects": {
"allow": { "type": "boolean" },
"deny": { "type": "boolean" },
"test_effect": {
"type": "object",
"properties": {
"level": { "type": "string" },
"message": { "type": "string" }
}
}
}
}
@@ -0,0 +1,83 @@
cases:
- note: "Microsoft Graph User Access Control - Allow Active User"
data: {}
input:
"@odata.type": "#microsoft.graph.user"
id: "12345678-1234-1234-1234-123456789012"
userPrincipalName: "john.doe@company.com"
displayName: "John Doe"
givenName: "John"
surname: "Doe"
mail: "john.doe@company.com"
jobTitle: "Software Engineer"
department: "Engineering"
accountEnabled: true
userType: "Member"
modules:
- |
package msgraph.user.allow
import rego.v1
__target__ := "target.tests.msgraph"
default allow := false
allow if {
input["@odata.type"] == "#microsoft.graph.user"
input.accountEnabled == true
input.userType == "Member"
}
query: data.msgraph.user.allow.allow
want_result: true
- note: "Microsoft Graph User Access Control - Block Disabled User"
data: {}
input:
"@odata.type": "#microsoft.graph.user"
id: "87654321-4321-4321-4321-210987654321"
userPrincipalName: "disabled.user@company.com"
displayName: "Disabled User"
accountEnabled: false
userType: "Member"
modules:
- |
package msgraph.user.block
import rego.v1
__target__ := "target.tests.msgraph"
block := {
"reason": "User account is disabled",
"blockType": "signin"
} if {
input["@odata.type"] == "#microsoft.graph.user"
input.accountEnabled == false
}
query: data.msgraph.user.block.block
want_result:
reason: "User account is disabled"
blockType: "signin"
- note: "Microsoft Graph Invalid Resource Type"
data: {}
input:
"@odata.type": "#microsoft.graph.unknownResource"
id: "test"
modules:
- |
package msgraph.invalid
import rego.v1
__target__ := "target.tests.msgraph"
default allow := false
allow if {
input["@odata.type"] == "#microsoft.graph.user"
input.accountEnabled == true
}
query: data.msgraph.invalid.allow
want_result: false
@@ -0,0 +1,455 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# Tests for resource type inference functionality
# The infer_resource_type function looks for patterns like input.<selector> == "resource_type"
# in effect rules and builds a mapping of queries to their inferred resource types and schemas.
cases:
- note: "target/infer_resource_type_basic_equality"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.basic_inference
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# This should infer resource type "test_resource" from the equality check
allow if {
input.type == "test_resource"
input.name != ""
}
query: data.policy.basic_inference.allow
want_result: true
want_inferred_resource_types: ["test_resource"]
- note: "target/infer_resource_type_multiple_equality_checks"
data: {}
input: {"type": "test_resource", "name": "example", "status": "active"}
modules:
- |
package policy.multiple_checks
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Multiple conditions with resource type check
allow if {
input.type == "test_resource"
input.status == "active"
input.name != ""
}
query: data.policy.multiple_checks.allow
want_result: true
want_inferred_resource_types: ["test_resource"]
- note: "target/infer_resource_type_complex_target_compute"
data: {}
input: {"resourceType": "compute", "name": "vm1", "spec": {"cpu": 4, "memory": "8Gi"}}
modules:
- |
package policy.complex_compute
import rego.v1
__target__ := "target.tests.complex_target"
default allow := false
# Should infer "compute" resource type from complex target
allow if {
input.resourceType == "compute"
input.spec.cpu >= 2
input.spec.memory
}
query: data.policy.complex_compute.allow
want_result: true
want_inferred_resource_types: ["compute"]
- note: "target/infer_resource_type_complex_target_storage"
data: {}
input: {"resourceType": "storage", "name": "disk1", "spec": {"size": "100Gi", "type": "ssd"}}
modules:
- |
package policy.complex_storage
import rego.v1
__target__ := "target.tests.complex_target"
default deny := false
# Should infer "storage" resource type from complex target
deny if {
input.resourceType == "storage"
input.spec.type == "hdd" # Deny HDDs
}
query: data.policy.complex_storage.deny
want_result: false
want_inferred_resource_types: ["storage"]
- note: "target/infer_resource_type_default_schema_usage"
data: {}
input: {"resourceType": "unknown_type", "name": "mystery_resource"}
modules:
- |
package policy.default_schema
import rego.v1
__target__ := "target.tests.complex_target"
default allow := false
# Should use default schema for unknown resource types
allow if {
input.resourceType == "unknown_type"
input.name != ""
}
query: data.policy.default_schema.allow
want_result: true
want_inferred_resource_types: ["unknown_type"]
- note: "target/infer_resource_type_multiple_rules_same_effect"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.multiple_rules
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# First rule with resource type check
allow if {
input.type == "test_resource"
input.name == "example"
}
# Second rule with different resource type check (should also be inferred)
allow if {
input.type == "other_resource"
input.status == "approved"
}
query: data.policy.multiple_rules.allow
want_result: true
want_inferred_resource_types: ["test_resource", "other_resource"] # Should infer both types from different rules
- note: "target/infer_resource_type_no_equality_check"
data: {}
input: {"name": "example", "status": "active"}
modules:
- |
package policy.no_type_check
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# No resource type equality check - should resolve to default schema
allow if {
input.name == "example"
input.status == "active"
}
query: data.policy.no_type_check.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema
- note: "target/infer_resource_type_wrong_equality_direction"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.wrong_direction
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Equality check in wrong direction (should still be detected)
allow if {
"test_resource" == input.type
input.name != ""
}
query: data.policy.wrong_direction.allow
want_result: true
want_inferred_resource_types: ["test_resource"]
- note: "target/infer_resource_type_array_access_selector"
data: {}
input: {"metadata": {"type": "test_resource"}, "name": "example"}
modules:
- |
package policy.array_access
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Using array-style access for the selector field
allow if {
input["type"] == "test_resource"
input.name != ""
}
query: data.policy.array_access.allow
want_result: false # This input doesn't have input.type, only input.metadata.type
want_inferred_resource_types: ["test_resource"]
- note: "target/infer_resource_type_variable_in_equality"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.variable_equality
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Using a variable in the equality (resolves to default schema since not a literal string)
resource_type := "test_resource"
allow if {
input.type == resource_type
input.name != ""
}
query: data.policy.variable_equality.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema since not a literal string
- note: "target/infer_resource_type_non_string_literal"
data: {}
input: {"priority": 5, "name": "example"}
modules:
- |
package policy.non_string
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Non-string literal equality (resolves to default schema)
allow if {
input.priority == 5
input.name != ""
}
query: data.policy.non_string.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema
- note: "target/infer_resource_type_not_first_statement"
data: {}
input: {"type": "test_resource", "name": "example", "status": "active"}
modules:
- |
package policy.not_first_statement
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Resource type check is not the first statement (should still be inferred)
allow if {
input.name != ""
input.status == "active"
input.type == "test_resource"
}
query: data.policy.not_first_statement.allow
want_result: true
want_inferred_resource_types: ["test_resource"]
- note: "target/infer_resource_type_nested_condition_not_inferred"
data: {}
input: {"type": "test_resource", "name": "example", "nested": {"resourceType": "compute"}}
modules:
- |
package policy.nested_condition
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Nested condition with resource type check (should not be inferred at nested level)
allow if {
input.name == "example"
some condition
condition := input.nested.resourceType == "compute"
condition
}
query: data.policy.nested_condition.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema (nested not inferred)
- note: "target/infer_resource_type_nested_rule_not_inferred"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.nested_rule
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Helper rule with nested type check (should not be inferred from helper rules)
is_valid_resource(resource_type) if {
resource_type == "test_resource"
}
# Main rule that uses helper (should resolve to default schema)
allow if {
input.name == "example"
is_valid_resource(input.type)
}
query: data.policy.nested_rule.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema (helper rule not inferred)
- note: "target/infer_resource_type_comprehension_not_inferred"
data: {}
input: {"type": "test_resource", "name": "example", "resources": [{"type": "compute"}, {"type": "storage"}]}
modules:
- |
package policy.comprehension
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Type check inside comprehension (should not be inferred)
allow if {
input.name == "example"
valid_resources := [r | r := input.resources[_]; r.type == "compute"]
count(valid_resources) > 0
}
query: data.policy.comprehension.allow
want_result: true
want_inferred_resource_types: ["default"] # Should resolve to default schema (comprehension not inferred)
- note: "target/infer_resource_type_multiple_types_same_rule"
data: {}
input: {"type": "test_resource", "name": "example"}
modules:
- |
package policy.multiple_types_same_rule
import rego.v1
__target__ := "target.tests.sample_test_target"
default allow := false
# Single rule with multiple resource type checks (should infer both)
allow if {
input.name == "example"
input.type == "test_resource"
input.type == "other_resource" # This will never match, but should still be inferred
}
query: data.policy.multiple_types_same_rule.allow
want_result: false # Will never match since input.type can't be both values
want_inferred_resource_types: ["test_resource", "other_resource"]
- note: "target/infer_resource_type_multiple_types_different_rules"
data: {}
input: {"resourceType": "compute", "name": "vm1", "spec": {"cpu": 4}}
modules:
- |
package policy.multiple_types_different_rules
import rego.v1
__target__ := "target.tests.complex_target"
default allow := false
# First rule checks for compute
allow if {
input.resourceType == "compute"
input.spec.cpu >= 2
}
# Second rule checks for storage
allow if {
input.resourceType == "storage"
input.spec.size
}
# Third rule checks for network
allow if {
input.resourceType == "network"
input.spec.subnet
}
query: data.policy.multiple_types_different_rules.allow
want_result: true
want_inferred_resource_types: ["compute", "storage", "network"]
- note: "target/infer_resource_type_invalid_schema_error"
data: {}
input: {"type": "invalid_resource", "name": "example"}
modules:
- |
package policy.invalid_schema
import rego.v1
__target__ := "target.tests.nonexistent_target"
default allow := false
# Reference to a target that doesn't exist in the registry
allow if {
input.type == "test_resource"
input.name != ""
}
query: data.policy.invalid_schema.allow
error: "Target 'target.tests.nonexistent_target' not found in registry"
- note: "target/infer_resource_type_missing_default_schema_error"
data: {}
input: {"name": "example", "status": "active"}
modules:
- |
package policy.missing_default_schema
import rego.v1
__target__ := "target.tests.no_default_schema_target"
default allow := false
# No type check, should trigger missing default schema error
allow if {
input.name == "example"
input.status == "active"
}
query: data.policy.missing_default_schema.allow
error: "Missing default resource schema: Target 'target.tests.no_default_schema_target' has no default resource schema"