Documentation
¶
Overview ¶
Package reporter writes kyverno-runtime findings to namespaced OpenReports Report resources.
It is the redaction chokepoint of the event plane: this package makes leaks structurally impossible on the way out:
- Finding is a CLOSED struct — typed scalar fields only. There is no header map, no body field, and no free-form properties passthrough, so an unredacted payload is not even representable at the boundary.
- buildResult emits a FIXED key set into ReportResult.Properties, and every emitted value passes through sanitize (see redact.go).
- PodIdentity.Labels are deliberately never emitted: arbitrary user-controlled key/values have no place in a Report.
None of this is configurable — there is no option, flag, or field that disables or weakens it (DESIGN §4).
Index ¶
Constants ¶
const ( ResultFail = "fail" ResultWarn = "warn" )
Result values emitted by this package. Monitor findings are "fail"; "warn" is available for advisory findings. No other OpenReports result value is ever produced by kyverno-runtime.
const ( DefaultMaxResultsPerReport = 500 DefaultFlushInterval = 10 * time.Second )
Defaults for Options.
const ( LabelManagedBy = "app.kubernetes.io/managed-by" LabelNode = "runtime.nirmata.io/node" // LabelPodUID identifies which incarnation of the Report's named pod its // results describe, so a pod recreated under the same name is detected as // a new incarnation instead of inheriting its predecessor's findings. LabelPodUID = "runtime.nirmata.io/pod-uid" )
Labels applied to every Report this package writes.
const AnnotationTruncatedResults = "runtime.nirmata.io/truncated-results"
AnnotationTruncatedResults is set to "true" on a Report whose results were capped at Options.MaxResultsPerReport. Silence must never read as safety: an operator can always tell that findings were dropped.
const Category = "Runtime Security"
Category groups every result kyverno-runtime emits.
const Redacted = "REDACTED"
Redacted replaces every credential- or payload-shaped substring found in a value on its way into a Report. It is a constant: there is no knob, flag, or option that changes or disables it.
const Source = "kyverno-runtime"
Source identifies kyverno-runtime as the engine that owns the reports it writes, both at the Report and the ReportResult level.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DNSSummary ¶
type DNSSummary struct {
QName string
}
DNSSummary summarizes the observed question of a dns finding.
type Finding ¶
type Finding struct {
PolicyName string
PolicyUID string
Behavior string // "network"|"open"|"exec"|"protocol"|"dns"
// Target is the behavior's object: the destination, path, executed
// binary, protocol[/alpn], or question name the message names.
Target string
Result string // "fail"|"warn" (observation-only findings are "warn")
// Enforced is true when the kernel actually denied the operation (an
// enforce-mode policy's maps blocked it); false for monitor mode's
// "would have been denied" counterfactual findings.
Enforced bool
Message string
Pod runtimeevent.PodIdentity
Net *NetSummary
DNS *DNSSummary
Process *ProcessSummary
Timestamp time.Time
}
Finding is a CLOSED struct: typed scalar fields only. There is no headers map, no body field, no free-form properties passthrough. This is the redaction boundary: what is not representable cannot leak.
func (Finding) Fingerprint ¶
Fingerprint identifies a finding across flushes so repeats merge into one Report result with a count instead of growing the report unboundedly.
It deliberately excludes the message, timestamp, and every free-text field: two occurrences of the same policy hitting the same target from the same pod are the same finding.
type NetSummary ¶
NetSummary summarizes the destination of a network finding.
type Options ¶
type Options struct {
// NodeName is the value of the node label on every Report this daemon
// writes.
NodeName string
// MaxResultsPerReport caps results per Report (default 500). Reports at
// the cap carry the truncated-results annotation.
MaxResultsPerReport int
// FlushInterval is how often buffered findings are written (default 10s).
FlushInterval time.Duration
// Clock is injectable for tests; defaults to time.Now.
Clock func() time.Time
}
Options configures a Reporter. The zero value is usable: every field has a default. Note that no option touches redaction — that is deliberate and permanent (DESIGN §4).
type ProcessSummary ¶
ProcessSummary summarizes the process of an exec/open finding.
type Reporter ¶
type Reporter struct {
// contains filtered or unexported fields
}
Reporter buffers findings, deduplicates them by fingerprint, and flushes them into namespaced OpenReports Report resources.
func (*Reporter) Report ¶
Report enqueues a finding. It never blocks on the API server: repeats of a fingerprint merge into the buffered entry (count, firstTimestamp, lastTimestamp) and the next flush writes the merged result.
Findings without a usable pod namespace and name are dropped: they cannot address a namespaced Report. Attribution normally guarantees both (unattributed events are dropped upstream), so this is both a safety net and — because an unvalidated value would otherwise be echoed into object metadata, bypassing sanitize — part of the redaction boundary.