ADR-0207: Target collection filtering — intent vs Scope ceiling¶
Theme: 02 · API & tenancy · Status: Current
Context¶
Operators need whitelist and blacklist collection policy at namespace, GVK, label, and attribute levels without patching Namespace objects or watching every object a Profile can extract. ADR-0201 deferred target-side filters; ADR-0205 watch labels address tenant consent, not platform exclusion or Trivy severity gates.
Maintainer decisions (rev 3, Option 1):
- Target / ClusterTarget — collection intent (
includedNamespaces,excludedNamespaces,namespaceExcludeSelector,resourceRules[], per-rulematchPolicyCEL). - Scope / ClusterScope — hard ceiling only (
allowedGVKs,allowedNamespaces,deniedNamespaces); noresourceRuleson Scope. - Profile — extraction only; same Profile reusable across broad vs narrow Targets.
- Inventory — no pre-store filters (export-time row filter remains deferred).
Decision¶
Phase 1 — namespace intent + Scope deny¶
| Field | CRD |
|---|---|
includedNamespaces, excludedNamespaces, namespaceExcludeSelector |
KollectTarget, KollectClusterTarget |
deniedNamespaces |
KollectScope, KollectClusterScope |
Phase 2 — resourceRules[]¶
Structured rules on Target: gvk, optional namespaceSelector, matchLabels /
matchExpressions. Empty resourceRules falls back to Profile targetGVK + Target
labelSelector / names (backward compatible).
Multiple rules are OR-unioned (label rule OR CEL severity for Trivy).
Phase 3 — CEL matchPolicy¶
Optional per-rule CEL evaluated after informer event, before store insert (not export-only).
Reuses the collect engine CEL environment with object bound to the resource.
Evaluation order¶

- Helm
watchNamespaces/ operator cache boundary - Scope
deniedNamespaces(non-overridable) - Target include intent (
includedNamespaces∩namespaceSelector) - Target exclude (
excludedNamespaces,namespaceExcludeSelector) - Scope
allowedNamespacescap resourceRules[]union (OR)- Per-rule
matchPolicyCEL - Scope
allowedGVKs(admission + reconcile) ShouldCollectwatch labels (ADR-0205)
Effective namespaces:
(Target intent) ∩ (Scope allowedNamespaces if set) \ (Target exclude ∪ Scope denied ∪ Helm exclude defaults)
Helm defaultIncludedNamespaces / defaultExcludedNamespaces apply when CRD fields are empty;
CRD overrides chart defaults.
Status¶
Targets expose status.matchedNamespaces, status.effectiveNamespaces, status.activeResourceRules.
Admission¶
Validating webhooks reject Target includedNamespaces outside Scope allowedNamespaces, any
intent namespace in Scope deniedNamespaces, and GVKs outside allowedGVKs. Reconcile degrades
as backstop (ScopeNamespaceDenied, ScopeGVKDenied).
Consequences¶
- Platform can deny
kube-systemvia Scope without Namespace patch RBAC. - Teams express Trivy HIGH-only collection without a dedicated Profile per severity slice.
KollectCollectionRuleCRD deferred until inline rules prove insufficient.- RBAC generation should eventually union GVKs from
resourceRules(follow-up).