Repository navigation
feat: install the OpenFeature Operator (runtime feature-flag layer) - #2527
Conversation
Adds the OpenFeature Operator (OFO) v0.9.2 to the shared infrastructure controller set as the platform's GitOps-native runtime per-request feature-flag layer (Part of #2510 / monorepo#2059). Landed default-OFF: the controller + its core.openfeature.dev/v1beta1 CRDs install, but no workload consumes a flag yet, so no flagd sidecar is injected and no flagd-proxy is created. Follows the flagger/kro controller pattern: HelmRepository + HelmRelease (dependsOn cert-manager for webhook TLS), a keda-style namespace (OFO ships only a partial securityContext with no override value, so native PSA restricted is skipped in favour of the Kyverno add-security-context backstop), a cilium-network-policy allowing kube-apiserver->webhook:9443 ingress plus kube-apiserver/DNS egress, and a drain-safe PDB (replicas: 2, leader-elected). Documents the four-layer feature-flag model (flagd/OFO runtime, Flagger release, Helm/Kustomize coarse, --feature-gates platform) in AGENTS.md ## Maintenance. Part of #2510 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds a new Flux-managed OpenFeature Operator deployment under the infrastructure controllers base, including a Namespace, HelmRepository, HelmRelease (with CRD management, cert-manager dependency, and HA replicas), CiliumNetworkPolicy for ingress/egress restrictions, PodDisruptionBudget, and a local kustomization.yaml wiring these resources together. The controllers aggregate kustomization is updated to include the new directory. AGENTS.md is updated with a new subsection documenting a four-layer feature-flag placement model and related validation.skipKinds guidance. Changes
Sequence Diagram(s)sequenceDiagram
participant Flux
participant HelmRepository
participant HelmRelease
participant CiliumNetworkPolicy
participant OpenFeatureOperator
Flux->>HelmRepository: fetch chart index
Flux->>HelmRelease: reconcile release (CreateReplace CRDs)
HelmRelease->>OpenFeatureOperator: deploy controller manager (2 replicas)
OpenFeatureOperator->>CiliumNetworkPolicy: ingress on 9443 from apiserver
OpenFeatureOperator->>CiliumNetworkPolicy: egress to kube-apiserver and kube-dns
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml`:
- Around line 50-60: The openfeature-operator Helm release currently sets
controllerManager.replicas but leaves controllerManager.resources unspecified,
so add an explicit resources override to satisfy the cluster’s LimitRange and
QoS expectations for an HA controller. Update the helm-release values under
controllerManager in this manifest to define appropriate requests and limits,
using the existing controllerManager block as the place to configure them.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d4019bdc-3d13-4070-b7ef-dd7c1d638cca
📒 Files selected for processing (8)
AGENTS.mdk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
devantler-tech/actions(auto-detected)devantler-tech/aws(auto-detected)devantler-tech/ksail(auto-detected)devantler-tech/reusable-workflows(auto-detected)devantler-tech/wedding-app(auto-detected)devantler-tech/ascoachingogvaner(auto-detected)devantler-tech/unifi(auto-detected)devantler-tech/provider-upjet-unifi(auto-detected)devantler-tech/agent-skills(auto-detected)
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
k8s/bases/**
📄 CodeRabbit inference engine (AGENTS.md)
Base files are immutable; do not edit k8s/bases directly from overlays. Make changes via Kustomize patches in overlays instead.
Files:
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
k8s/bases/infrastructure/**
📄 CodeRabbit inference engine (AGENTS.md)
k8s/bases/infrastructure/**: Infrastructure resources under k8s/bases/infrastructure/ must follow the component-folder-first structure, with related HelmRelease/HelmRepository and CRs colocated unless explicitly split into a plural-Kind folder for dependency or cluster-scoped reasons.
Use plural-Kind folders only when a CR cannot live with its component, such as when it must reconcile a layer later for CRD ordering or because it is cluster-scoped/cross-cutting.
Follow the established Flux dependency order: bootstrap → infrastructure-controllers → infrastructure → apps; keep prod-only side layers and app resources in the appropriate layer.
Files:
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
k8s/bases/infrastructure/controllers/**
📄 CodeRabbit inference engine (AGENTS.md)
Controller-layer resources should keep component-related manifests together in the controller folder unless a dependency split is required.
Files:
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
k8s/**
📄 CodeRabbit inference engine (AGENTS.md)
Validate Kubernetes manifest changes before submitting a manifest PR using ksail workload validate (preferred) or kubectl kustomize / kubectl apply --dry-run=client as appropriate.
Files:
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: devantler-tech/platform
Timestamp: 2026-07-07T17:54:07.757Z
Learning: Always reference AGENTS.md instructions first and fall back to search or ad-hoc commands only when something is not covered here.
Learnt from: CR
Repo: devantler-tech/platform
Timestamp: 2026-07-07T17:54:07.757Z
Learning: Use Conventional Commit messages and draft PRs for changes; keep PRs small and focused.
Learnt from: CR
Repo: devantler-tech/platform
Timestamp: 2026-07-07T17:54:07.757Z
Learning: Never commit plaintext secrets; all secrets must be SOPS-encrypted and use the .enc.yaml suffix.
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.
Applied to files:
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yamlk8s/bases/infrastructure/controllers/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yamlk8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yamlk8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yamlk8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
🪛 Trivy (0.69.3)
k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
[info] 6-16: limit range usage
A LimitRange policy with a default requests and limits for each container should be configured
Rule: KSV-0039
(IaC/Kubernetes)
k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
[info] 7-10: limit range usage
A LimitRange policy with a default requests and limits for each container should be configured
Rule: KSV-0039
(IaC/Kubernetes)
k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
[info] 14-60: limit range usage
A LimitRange policy with a default requests and limits for each container should be configured
Rule: KSV-0039
(IaC/Kubernetes)
k8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
[info] 6-44: limit range usage
A LimitRange policy with a default requests and limits for each container should be configured
Rule: KSV-0039
(IaC/Kubernetes)
🔀 Multi-repo context
Linked repositories findings
devantler-tech/ksail
pkg/apis/cluster/v1alpha1/types.go:218-223—spec.workload.validation.skipKindsandschemaLocationsalready exist in the config schema. This aligns with the PR’s newksail.yamlguidance for skipping newly installed runtime CRDs.docs/src/content/docs/cli-flags/workload/workload-validate.mdx:47andpkg/cli/cmd/workload/validate.go:127-131,249,414-431—--skip-kindsis merged withspec.workload.validation.skipKinds, so the new docs note about addingskipKindsfor runtime-installed CRDs is consistent with the current validation flow.pkg/fsutil/configmanager/talos/apiserver_feature_gates_test.go:1-26,35-52— ksail already has Talos apiserver feature-gate patching (MutatingAdmissionPolicy=true,runtime-config=...), which matches the PR’s new four-layer feature-flag guidance for platform-level feature gates.
devantler-tech/wedding-app
- No
FeatureFlag,openfeature,open-feature,flagd,flipper,feature-gate, orskipKindsreferences found.
devantler-tech/reusable-workflows
- No
FeatureFlag,openfeature,open-feature,flagd,flipper,feature-gate, orskipKindsreferences found.
🔇 Additional comments (8)
k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yaml (1)
1-17: LGTM!k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml (1)
1-11: LGTM!k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml (1)
1-49: LGTM!k8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml (1)
1-45: LGTM!k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml (1)
1-10: LGTM!k8s/bases/infrastructure/controllers/kustomization.yaml (1)
30-30: LGTM!AGENTS.md (1)
347-354: LGTM!k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml (1)
14-16: 🩺 Stability & AvailabilityConfirm the controller pods use
app.kubernetes.io/name: open-feature-operator.If the chart applies different pod labels, this PDB matches nothing and won’t protect drains.
|
🎉 This PR is included in version 1.108.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Why. The platform has no per-request/per-feature runtime flag layer — new behaviour goes live on reconcile with no GitOps-native way to land a feature off, validate it, then flip it on. This is the last open child of the portfolio-wide feature-flag-first program (monorepo#2059); every other stack (ksail, actions, astro, go/dotnet templates) already has its mechanism.
What. Installs the OpenFeature Operator (v0.9.2) as the platform's runtime feature-flag layer, following the existing controller pattern (like flagger/kro). It lands default-off and latent: the controller and its CRDs install, but nothing consumes a flag yet, so no sidecars or proxy are created — zero behavioural change until a workload opts in later. Also documents the platform's four-layer feature-flag model (flagd runtime / Flagger release / Helm-values coarse /
--feature-gates) inAGENTS.md.New dependency / operational note. Adds one new operator to the shared infra-controller set (depends on cert-manager for its webhook TLS). Manifests are statically validated (
ksail workload validate, 533 files, both overlays), but the operator's live health — webhook admission, the PSA/Kyverno securityContext handling, network policy — can only be confirmed on a real cluster, so promotion is the live-validation gate (that's the feature-flag-first "land off, validate, then flip" flow).Follow-ups (deferred,
Part of #2510): the first exampleFeatureFlagCR + itsskipKindsentry, a CI flag-definition schema check, and the first real consumer (a tenant web app via flagd-proxy).Part of #2510