# kyverno-json Engine Adapter (v1.25) The `kyverno-json` engine is Nova's **primary compliance/policy tool** (v1.25), implemented behind the swappable `PolicyEngine` protocol so OPA (or any other engine) can replace it one day. ## What kyverno-json is [kyverno-json](https://github.com/kyverno/kyverno-json) is a standalone Go binary from the Kyverno project — a **separate runtime** from the K8s Kyverno admission controller. It applies Kyverno `ValidatingPolicy` resources to **any** JSON or YAML payload file via the `kj scan` CLI. Unlike the K8s Kyverno adapter (`adapters/kyverno/`), which only speaks to K8s manifests, kyverno-json evaluates consumer contracts, resolved Stack IR, terraform plan JSON, and even the merged PCR list itself (meta-policies). ## Install ```bash bash scripts/install-kyverno-json.sh # or directly: go install github.com/kyverno/kyverno-json/cmd/kj@latest kj version ``` The platform functions without the binary — `is_configured()` returns `False` when `which kj` is absent → `evaluate()` returns a single `SKIPPED` PCR (`KJ_ENGINE_NOT_CONFIGURED`). The confidence signal proceeds with a neutral `policy` input (D-120 graceful degradation). ## Policy directory layout ``` adapters/kyverno-json/policies/ ├── _smoke.json # round-trip smoke test ├── contract/ # consumer contract JSON policies │ ├── require-id-pattern.json │ ├── require-env-in-enum.json │ ├── require-infrastructure-min-1.json │ └── forbid-unknown-fields.json ├── stack-ir/ # resolved Stack IR policies │ ├── require-tagging-standard.json │ ├── forbid-public-ingress.json │ └── require-encryption-by-default.json ├── plan-json/ # terraform show -json policies │ ├── forbid-plaintext-secrets.json │ ├── forbid-iam-wildcard.json │ └── require-kms-reference.json ├── meta/ # policies over the merged PCR list │ ├── block-on-any-critical.json │ └── tagging-rules-agree.json └── regression/ # capability-inventory policies ├── cap-013-adapter-dedup.json ├── cap-023-metrics-collector.json └── cap-024-deck-structure.json ``` ## The four policy categories 1. **contract/** — over the consumer contract JSON (pre-resolve). 2. **stack-ir/** — over the resolved Target Stack IR (post-resolve). 3. **plan-json/** — over `terraform show -json` output (pipeline Step 5b). 4. **meta/** — over the merged `list[PolicyCheckResult]` (meta-policies). 5. **regression/** — over the capability-inventory JSON (declarative mirrors of `core/regression_verify.py`). ## Severity convention kyverno-json does not natively assign severities. Each Nova policy declares its severity via a `metadata.annotations` field: ```yaml metadata: annotations: nova.cloudinit.dev/severity: high ``` Valid values: `critical`, `high`, `medium`, `low`, `info` (default when absent). ## Engine enum reuse (D-116) kyverno-json PCR records carry `engine: "kyverno"` (no new enum value). The `engine` field records the policy-engine *family*, not the specific binary. The K8s Kyverno adapter and the kyverno-json engine are distinguished by `ruleId` prefix (`KYVERNO_` vs `KJ_`) and `evidence` payload shape (`namespace`/`kind` vs `assertion`/`jmespath`). ## Schema path The output records validate against [`schemas/policy_check_result.schema.json`](../../schemas/policy_check_result.schema.json) (`engine: "kyverno"` is in the enum). The confidence signal consumes the merged PCR list engine-agnostically. ## Swap boundary The `PolicyEngine` protocol (`core/policy_engine.py`) is the swap boundary. The OPA-equivalent surface is documented in `.ciagent/RESEARCH.md` §4.2 — a future `OpaEngine` implements the same protocol without touching the confidence signal, the PCR schema, or the pipeline.