Skip to content

Add Rego engine parity, pure-engine architecture, and dynamic resource fetching#1

Merged
phenixblue merged 2 commits into
mainfrom
feature/rego-engine-parity
Apr 3, 2026
Merged

Add Rego engine parity, pure-engine architecture, and dynamic resource fetching#1
phenixblue merged 2 commits into
mainfrom
feature/rego-engine-parity

Conversation

@phenixblue
Copy link
Copy Markdown
Owner

Summary

This PR brings the Rego evaluation engine to full functional parity with the Go engine, restructures scan execution around a pure single-engine model, and adds infrastructure for custom policy bundles to declare and fetch arbitrary Kubernetes resource types at scan time.


Changes

Pure engine architecture

Previously, --engine rego ran Rego for catalog checks and then fell back to the Go engine for cluster (preflight) checks — a hidden hybrid that caused different output between the two engines. This has been removed.

  • scan.go now always builds a ClusterSnapshot first, then passes it to whichever engine is selected. Neither engine calls the other.
  • eval.RunRequest carries a *kube.ClusterSnapshot instead of raw findings.
  • The Go engine path is unchanged; the Rego engine receives the snapshot as input.cluster.

ClusterSnapshot + BuildClusterSnapshot

All cluster state is now serialised into a single kube.ClusterSnapshot struct before evaluation. This makes the snapshot independently testable and reusable across engines.

  • New internal/kube/snapshot.go: ClusterSnapshot, DeploymentSnapshot, NodeSnapshot, etc.
  • New internal/kube/build_snapshot.go: BuildClusterSnapshot() and DegradedSnapshot().
  • ClusterSnapshot.Resources map[string][]ResourceSnapshot carries dynamically-fetched resource types.

Dynamic resource fetching (--resource flag + bundle metadata)

Policy bundles can now declare the Kubernetes resource types they need in metadata.json. The scanner fetches them via the dynamic client and exposes them to Rego as input.cluster.resources["GROUP/VERSION/resources"]. A --resource CLI flag provides the same capability for ad-hoc use.

  • kube.Clients gains a dynamic.Interface field.
  • PreflightOptions.ResourceTypes []string drives fetching within BuildClusterSnapshot.
  • bundleMetadata.Resources []string in the Rego engine is read before snapshot building.
  • ResourceTypesFromBundle(bundlePath) is exported for use in scan.go.
  • mergeResourceTypes deduplicates the union of flag and bundle resource lists.
  • Resource type strings use the plural API path name (e.g. v1/configmaps, apps/v1/deployments) to match Kubernetes REST URL conventions.

Default Rego bundle (policy/)

A new standalone policy bundle under policy/ covers all checks previously handled by the Go engine:

File Purpose
policy/catalog.rego Validates check metadata (category + ID prefix taxonomy)
policy/cluster.rego All cluster preflight checks (KubeVirt, nodes, PSA, NetworkPolicy, PDB, guardrails, RBAC)
policy/main.rego Combines both into the required data.kvirtbp.findings entrypoint
policy/metadata.json Bundle metadata

The embedded internal/eval/rego/policy/baseline.rego was updated to the same combined logic for use with --engine rego without any flags.

Rego unit tests

New policy/catalog_test.rego (8 tests) and policy/cluster_test.rego (11 tests) cover the policy rules directly using opa test.

Custom bundle e2e test

A lightweight e2e scenario that exercises the full dynamic resource-fetching path without requiring KubeVirt:

  • test/fixtures/custom-bundle/ — policy that checks for a ConfigMap named kvirtbp-e2e-marker; metadata.json declares "resources": ["v1/configmaps"]
  • scripts/e2e_kind_custom_bundle.sh — creates a single-node kind cluster; pass mode deploys the ConfigMap, fail mode removes it

New Makefile targets

Target Purpose
make rego-check opa check --v0-compatible — syntax validation
make rego-fmt opa fmt --v0-compatible --write — formatting
make rego-test opa test --v0-compatible -v — unit tests (19/19 pass)
make e2e-kind-custom-bundle-pass / make e2e-kind-custom-bundle-fail Custom bundle e2e scenarios

All OPA CLI targets use --v0-compatible because the policies use classic (pre-v1) Rego syntax,
consistent with the github.com/open-policy-agent/opa v1.15.1 Go library in use.

Test coverage additions

  • internal/kube/preflight_controls_test.go — 4 tests for parseResourceType (core group, named group, CRD, invalid inputs)
  • internal/cli/scan_metadata_test.go — 3 tests for mergeResourceTypes (dedup, empty inputs, all-in-a)
  • internal/eval/rego/engine_test.go — 4 tests for ResourceTypesFromBundle (with resources, no resources field, missing metadata, non-existent path)
  • internal/eval/snapshot_rego_test.go — snapshot ↔ Rego equivalence tests
  • internal/eval/equivalence_bundle_test.go — Go engine vs Rego bundle parity tests

@phenixblue phenixblue added documentation Improvements or additions to documentation enhancement New feature or request labels Apr 3, 2026
@phenixblue phenixblue merged commit fdea00b into main Apr 3, 2026
4 checks passed
@phenixblue phenixblue deleted the feature/rego-engine-parity branch April 3, 2026 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant