Skip to content

Epic: Externalize Configuration & Multi-Layer Precedence System #109

Description

@cwiklik

Overview

Externalize all hardcoded sidecar configuration (images, ports, resource limits, UID) into a hot-reloadable PlatformConfig backed by Kubernetes ConfigMaps, add cluster-wide FeatureGates as a kill switch, and implement a 6-layer precedence chain that gives operators fine-grained per-sidecar injection control at the global, namespace, workload, and platform-default levels.

Related Issue #97

Goals

  • Replace all hardcoded container images, ports, resource limits, and UIDs with config-driven values from PlatformConfig
  • Add FeatureGates as the highest-priority injection kill switch (global + per-sidecar)
  • Implement a PrecedenceEvaluator with 6 layers: Global gate → Per-sidecar gate → Namespace label → Workload label → TokenExchange CR → Platform defaults
  • Hot-reload both configs via fsnotify (ConfigMap volume watch)
  • Add Helm chart support (ConfigMap templates, volume mounts, values.yaml defaults)
  • Preserve backward compatibility for deprecated Agent/MCPServer webhook paths

Out of Scope

  • TokenExchange CR integration (stub only — tokenExchangeOverrides parameter is nil)
  • CLI tooling for config management
  • Migration tooling from hardcoded to config-driven values

Implementation Phases (Stacked PRs)

PRs should be reviewed and merged in order. Each builds on the previous.

  • Phase 1: Configuration Foundation (feat/config-types)
    Add PlatformConfig and FeatureGates types, compiled defaults, YAML loaders with validation, and fsnotify-based file watchers for hot-reload. Purely additive — no existing code modified. ~575 lines.

  • Phase 2: Precedence Evaluator (feat/precedence-evaluator)
    Add the 6-layer precedence chain evaluator, per-sidecar injection decision types, and 27 table-driven tests. New files plus additive label constants. ~650 lines.

  • Phase 3: ContainerBuilder Refactor (feat/container-builder-refactor)
    Refactor Build*Container() from package-level functions to methods on a ContainerBuilder struct reading from *config.PlatformConfig. Temporary backward-compatible wrappers keep existing callers compiling. ~150 lines.

  • Phase 4: PodMutator Wiring & Main Integration (feat/pod-mutator-wiring)
    Rewrite InjectAuthBridge to use the precedence evaluator. Change NewPodMutator signature for config getter functions. Wire loaders in cmd/main.go. Remove temporary wrappers from Phase 3. ~300 lines.

  • Phase 5: Helm Chart, Scripts & Documentation (feat/helm-config-support)
    Add ConfigMap templates, deployment volume mounts, values.yaml defaults, rollout script updates, E2E test script, and README documentation. ~900 lines.

Precedence Chain Design

Layer 1: Global feature gate (kill switch)         → short-circuits all sidecars
Layer 2: Per-sidecar feature gate                   → short-circuits individual sidecar
Layer 3: Namespace label (kagenti-enabled=true)     → opt-in required
Layer 4: Workload label (kagenti.io/<sidecar>-inject=false) → opt-out per workload
Layer 5: TokenExchange CR override (stub)           → future per-workload CRD control
Layer 6: Platform defaults (sidecars.<name>.enabled) → lowest priority

Special rules:

  • proxy-init always follows envoy-proxy — never injected independently
  • spiffe-helper requires both precedence chain AND kagenti.io/spire=enabled label

Metadata

Metadata

Assignees

Labels

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions