Skip to content

feat: install the OpenFeature Operator (runtime feature-flag layer) - #2527

Merged
devantler merged 1 commit into
mainfrom
claude/feature-flags-openfeature-operator
Jul 7, 2026
Merged

devantler merged 1 commit into
mainfrom
claude/feature-flags-openfeature-operator

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Daily AI Assistant

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) in AGENTS.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 example FeatureFlag CR + its skipKinds entry, a CI flag-definition schema check, and the first real consumer (a tenant web app via flagd-proxy).

Part of #2510

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>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
OpenFeature Operator deployment Adds namespace, HelmRepository, HelmRelease, CiliumNetworkPolicy, PodDisruptionBudget, and kustomization wiring for the OpenFeature Operator; updates AGENTS.md with feature-flag layering guidance

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
Loading

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: installing the OpenFeature Operator as the runtime feature-flag layer.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the operator install and AGENTS.md updates.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between bb95a98 and 618475c.

📒 Files selected for processing (8)
  • AGENTS.md
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/cilium-network-policy.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/namespace.yaml
  • k8s/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.yaml
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/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.yaml
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/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.yaml
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/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.yaml
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/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.yaml
  • k8s/bases/infrastructure/controllers/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/kustomization.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/pod-disruption-budget.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-repository.yaml
  • k8s/bases/infrastructure/controllers/openfeature-operator/helm-release.yaml
  • k8s/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

Learn more

(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

Learn more

(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

Learn more

(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

Learn more

(IaC/Kubernetes)

🔀 Multi-repo context

Linked repositories findings

devantler-tech/ksail

  • pkg/apis/cluster/v1alpha1/types.go:218-223 — spec.workload.validation.skipKinds and schemaLocations already exist in the config schema. This aligns with the PR’s new ksail.yaml guidance for skipping newly installed runtime CRDs.
  • docs/src/content/docs/cli-flags/workload/workload-validate.mdx:47 and pkg/cli/cmd/workload/validate.go:127-131,249,414-431 — --skip-kinds is merged with spec.workload.validation.skipKinds, so the new docs note about adding skipKinds for 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, or skipKinds references found.

devantler-tech/reusable-workflows

  • No FeatureFlag, openfeature, open-feature, flagd, flipper, feature-gate, or skipKinds references 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 & Availability

Confirm 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.

@github-project-automation github-project-automation Bot moved this from 🫴 Ready to 🏃🏻‍♂️ In Progress in 🌊 Project Board Jul 7, 2026
@devantler
devantler marked this pull request as ready for review July 7, 2026 18:11
@devantler
devantler added this pull request to the merge queue Jul 7, 2026
Merged via the queue into main with commit 8165115 Jul 7, 2026
16 checks passed
@devantler
devantler deleted the claude/feature-flags-openfeature-operator branch July 7, 2026 19:22
@github-project-automation github-project-automation Bot moved this from 🏃🏻‍♂️ In Progress to ✅ Done in 🌊 Project Board Jul 7, 2026
@botantler-1

botantler-1 Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.108.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant