Ctrl K
ComunidadGuías…

pkg/policyreports/engine.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package policyreports

import "strings"

// Engine is the normalized policy/security engine that produced a Finding.
//
// It exists because a PolicyReport's `results[].source` is a *producer
// type*, not an engine. One engine emits several source values — a single
// Kyverno 1.18 cluster writes `kyverno` (legacy Policy/ClusterPolicy),
// `KyvernoValidatingPolicy`, and `KyvernoGeneratingPolicy` into the same
// report stream. Filtering on the raw string would fragment one engine
// into as many buckets as it has policy types, and every new upstream
// policy kind would silently create another bucket.
//
// Consumers that ask "what does Kyverno say about this resource" filter on
// Engine; consumers that need to name the exact producer keep reading
// Finding.Source.
type Engine string

const (
	// EngineKyverno — Kyverno, via either the legacy kyverno.io family or
	// the modern policies.kyverno.io CEL family.
	EngineKyverno Engine = "kyverno"
	// EngineVAP — Kubernetes-native ValidatingAdmissionPolicy /
	// MutatingAdmissionPolicy. Kyverno's reports controller can evaluate
	// VAPs and write the results into PolicyReports, but the evaluating
	// engine is the apiserver, so these are attributed to VAP rather than
	// to whichever controller happened to write the report.
	EngineVAP Engine = "vap"
	// EngineTrivy — Trivy Operator (vulnerability, config-audit, secret,
	// and SBOM reports).
	EngineTrivy Engine = "trivy"
	// EngineFalco — Falco runtime security, via a PolicyReport adapter.
	EngineFalco Engine = "falco"
	// EngineOther — the report named a producer we don't have a mapping
	// for. Distinct from EngineUnknown: the data is attributable, we just
	// don't recognize the name. Consumers should show it rather than drop
	// it, and the raw Source is the thing worth displaying.
	EngineOther Engine = "other"
	// EngineUnknown — the report carried no `source` at all. Older engines
	// and hand-written reports omit it. Never conflate this with
	// EngineOther: "nobody said" and "somebody we don't know" lead to
	// different operator conclusions.
	EngineUnknown Engine = "unknown"
)

// EnginesAttributableToKyverno is the engine set that may legitimately fill a
// Kyverno-labelled rollup.
//
// EngineUnknown is included deliberately. `results[].source` is optional and
// older Kyverno builds omit it, so those findings normalize to EngineUnknown.
// Excluding them would empty the Kyverno summary on exactly the legacy
// clusters this integration still has to serve, so an unattributed finding
// keeps the historical assumption that Kyverno wrote it.
//
// EngineVAP is deliberately NOT included, even though Kyverno's reports
// controller is what writes VAP results into PolicyReports: the evaluating
// engine is the apiserver, and a rollup labelled "kyverno" must not count
// enforcement Kyverno did not perform.
var EnginesAttributableToKyverno = []Engine{EngineKyverno, EngineUnknown}

// EngineForSource normalizes a raw PolicyReport `results[].source` value to
// the engine that produced it. Matching is case-insensitive and
// whitespace-trimmed because the field is free-form — nothing upstream
// validates it.
//
// Observed source values this maps (Kyverno 1.18, Trivy Operator 0.2x,
// falcosidekick's PolicyReport output):
//
//	kyverno, KyvernoValidatingPolicy, KyvernoImageValidatingPolicy,
//	KyvernoMutatingPolicy, KyvernoGeneratingPolicy      → kyverno
//	ValidatingAdmissionPolicy, MutatingAdmissionPolicy  → vap
//	Trivy Vulnerability, trivy-operator                 → trivy
//	falco, falcosidekick                                → falco
//
// Unrecognized non-empty values map to EngineOther; an empty source maps
// to EngineUnknown.
func EngineForSource(source string) Engine {
	s := strings.ToLower(strings.TrimSpace(source))
	if s == "" {
		return EngineUnknown
	}

	switch {
	// Prefix, not equality: the modern family appends the policy type
	// (KyvernoValidatingPolicy, KyvernoImageValidatingPolicy, ...) and
	// upstream adds new ones every release. Matching the prefix means a
	// policy kind Radar has never heard of still attributes correctly.
	case strings.HasPrefix(s, "kyverno"):
		return EngineKyverno
	// Suffix covers both ValidatingAdmissionPolicy and
	// MutatingAdmissionPolicy without enumerating them. Ordered after the
	// kyverno prefix so a hypothetical "KyvernoValidatingAdmissionPolicy"
	// attributes to the controller that owns the policy object.
	case strings.HasSuffix(s, "admissionpolicy"):
		return EngineVAP
	case strings.Contains(s, "trivy"):
		return EngineTrivy
	case strings.Contains(s, "falco"):
		return EngineFalco
	}
	return EngineOther
}