Phase 23 (v1.7) — tagging standards and security adapters.
* schemas/tagging-standard.json (D-054): canonical required-tags schema
(acdl:owner, acdl:contract, acdl:environment, acdl:cost-center).
* adapters/terraform/policy/custom_rules/acdl_tagging.py: Checkov custom
rule (ACDL_TAG_NAMING) loaded via --external-checks-dir; closes D-043
(synthetic SKIPPED record replaced by real PASS/FAIL records).
* checkov_adapter.py: removed _emit_tag_naming_skipped(), added
ACDL_TAG_NAMING to RULE_MAP, updated docstring.
* scripts/run_platform.sh: both Checkov invocations pass
--external-checks-dir adapters/terraform/policy/custom_rules/.
* adapters/wiz/ (D-052): Wiz adapter translating issue records to
PolicyCheckResult (engine: "wiz"); graceful degradation emits
WIZ_NOT_CONFIGURED SKIPPED when unconfigured; is_configured() gate.
* adapters/kyverno/ (D-053): Kyverno adapter translating PolicyReport
results to PolicyCheckResult (engine: "kyverno"); ready but inactive
for Terraform-only stacks; 3 sample ClusterPolicies in policies/.
* schemas/policy_check_result.schema.json: engine enum += "wiz".
* tests: fixtures + test_wiz_adapter.py (8 tests) + test_kyverno_adapter.py
(13 tests); updated test_checkov_adapter.py to not expect the removed
synthetic ACDL_TAG_NAMING SKIPPED record.
* scripts/run_ci.sh: lint stage compiles the new adapter modules.
202 tests pass; CI pipeline OK (lint + test + check-only).
Deviations:
- Wiz adapt() had an AttributeError on bare-list top-level input
(data.get() on a list); fixed to dispatch on isinstance(data, list)
before calling .get(). No spec change — bare-list handling is implied
by the original docstring's "data if isinstance(data, list)" branch.
- Kyverno _to_pcr({}) defaults result to "skipped" (entry.get("result",
"skip") -> "skip"), not "error"; test expectation corrected. Added an
explicit unknown-result-string test to cover the "error" fallback.
---ci---
project: acdl
phase: 23
milestone: v1.7
status: execute
---/ci---
3.1 KiB
Kyverno Adapter
The Kyverno adapter translates Kyverno PolicyReport results to the
normalized ACDL
PolicyCheckResult schema
(engine: "kyverno"), mirroring the Checkov/Wiz adapter pattern.
What Kyverno is
Kyverno is a Kubernetes-native policy engine. It
runs as an admission controller inside a cluster, validates / mutates /
generates K8s resources against declarative ClusterPolicy rules, and
publishes results to PolicyReport resources.
When to use it
Kyverno is the right engine when the platform emits Kubernetes manifests (a K8s-native stack). The ACDL platform today emits Terraform only (D-053), so this adapter is ready but inactive: it ships now so the schema path, severity/result mapping and sample policies are in place ahead of the GitOps reconciler that will emit K8s manifests (roadmap).
How the adapter translates PolicyReport results
kyverno_adapter.py <policyreport.json> <contract-id> reads a JSON file
containing a Kyverno PolicyReport (or just its .results[] array) and
emits a list of PolicyCheckResult dicts:
| Kyverno PolicyReport result field | PolicyCheckResult field |
|---|---|
policy |
ruleId (default KYVERNO_UNKNOWN) |
severity |
severity (lower-cased, mapped) |
result |
result (pass/fail/error as-is, warn/skip→skipped) |
message |
message |
resource |
resourceRef + evidence.resource |
namespace, kind, name |
evidence.* |
The adapter is read-only against a local JSON fixture; the GitOps
reconciler is responsible for fetching the live PolicyReport and writing
the file. When there are zero results, the adapter returns an empty list
(unlike Wiz it does not synthesize a SKIPPED record — Kyverno not running
is a deployment state, not a configuration gap).
Roadmap dependency
This adapter activates when the GitOps reconciler (roadmap) emits K8s
manifests. Until then it is documentation-only; the pipeline does not
invoke it. The engine: "kyverno" enum value is present in
schemas/policy_check_result.schema.json so future records validate.
Sample policies
The policies/ directory holds three valid Kyverno ClusterPolicy
manifests (documentation-only today — the platform does not run them):
disallow-privileged-containers.yaml— fail pods withsecurityContext.privileged: true.require-resource-labels.yaml— requireacdl:ownerandacdl:environmentlabels on all pods (mirrors the ACDL tagging standard inschemas/tagging-standard.json).require-image-digests.yaml— require container images to reference a digest (image@sha256:...), not a mutable tag.
Schema path
The output records validate against
schemas/policy_check_result.schema.json
(engine: "kyverno" was already in the enum and is retained in Phase 23).