Skip to content

feat(platform): add opt-in in-cluster east-west encryption toggle - #2984

Merged
Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
feat/networking-encryption
Jul 27, 2026
Merged

Aleksei Sviridkin (lexfrei) merged 1 commit into
mainfrom
feat/networking-encryption

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

Adds networking.encryption.enabled to the platform chart — a single operator-facing opt-in, off by default, that turns on in-cluster (east-west) transport encryption for the active datapath. When enabled, pod-to-pod traffic across nodes is encrypted at the network layer regardless of whether the workload implements TLS: defense-in-depth for the whole mesh without per-application changes.

The default isp-full bundle selects the kubeovn-cilium datapath (and isp-full-generic selects kubeovn-cilium-generic), where KubeOVN owns the datapath and the overlay is a Geneve tunnel. The toggle therefore maps to KubeOVN's overlay IPsec (kube-ovn ENABLE_OVN_IPSEC). KubeOVN's own controller provisions the IPsec CA and per-node certificates through the Kubernetes CSR API, so no cert-manager wiring is needed.

This complements, and does not replace, application-level / end-to-end TLS: in-cluster encryption never reaches an external client and gives a tenant no verifiable endpoint certificate. The values comments document the per-datapath scope — including that Kilo's WireGuard mesh (meshGranularity: location) covers only cross-location traffic and leaves the intra-location gap this toggle targets, and that the Cilium-native WireGuard/IPsec path on the cilium / cilium-generic variants is not reached because the system bundle does not select those variants — plus the MTU/throughput overhead.

Scope: only the default KubeOVN datapath is wired through the platform toggle, which is what the system bundle actually selects. Wiring the Cilium-native path would require the bundle to expose cilium-only variant selection; that is out of scope here and called out in the values comments.

Validation: helm unittest on the platform chart passes (66 tests, 7 new) covering on / off / absent / null and verifying the IPsec flag deep-merges without dropping the existing kube-ovn overrides, for both isp-full and isp-full-generic.

Closes #2977

Part of #2811

Screenshots

N/A — no UI changes.

Release note

feat(platform): add opt-in `networking.encryption.enabled` (off by default) that enables in-cluster east-west transport encryption for the default KubeOVN datapath via overlay IPsec; complements, and does not replace, application-level TLS.

Summary by CodeRabbit

  • New Features

    • Introduced opt-in in-cluster network encryption using KubeOVN IPsec for east-west traffic protection.
    • Added networking.encryption configuration toggle (disabled by default) with full backward compatibility.
  • Tests

    • Added comprehensive test coverage for network encryption configurations across system variants and edge cases.

Add networking.encryption.enabled (off by default), a platform-level
opt-in that turns on in-cluster transport encryption for the active
datapath. On the default kubeovn-cilium datapath (and its generic
variant) KubeOVN owns the overlay, so the toggle maps to KubeOVN's
Geneve-overlay IPsec (kube-ovn ENABLE_OVN_IPSEC). KubeOVN's controller
provisions the IPsec CA and per-node certificates through the
Kubernetes CSR API, so no cert-manager wiring is required.

This is defense-in-depth for the whole mesh without per-application
changes; it complements, and does not replace, application-level /
end-to-end TLS. Values comments document the per-datapath scope
(including Kilo's cross-location-only mesh and the unreached
Cilium-native path on cilium/cilium-generic variants) and the
MTU/throughput overhead.

Assisted-By: Claude <[email protected]>
Signed-off-by: Aleksei Sviridkin <[email protected]>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bda30d4c-febb-423c-8ece-95e8965085a2

📥 Commits

Reviewing files that changed from the base of the PR and between 77d42ab and aced011.

📒 Files selected for processing (3)
  • packages/core/platform/templates/bundles/system.yaml
  • packages/core/platform/tests/bundles_networking_encryption_test.yaml
  • packages/core/platform/values.yaml

📝 Walkthrough

Walkthrough

Adds an opt-in networking.encryption.enabled toggle (default false) to the platform values.yaml. When enabled, the system.yaml Helm template injects ENABLE_OVN_IPSEC=true into the KubeOVN configuration for both isp-full and isp-full-generic bundle variants. A new test suite validates on/off/nil/deep-merge rendering behavior.

Changes

KubeOVN IPsec encryption toggle

Layer / File(s) Summary
Values contract and template rendering
packages/core/platform/values.yaml, packages/core/platform/templates/bundles/system.yaml
Adds networking.encryption block with enabled: false default and per-datapath documentation in values.yaml; adds conditional ENABLE_OVN_IPSEC=true injection for both isp-full and isp-full-generic variants in system.yaml.
Encryption test suite
packages/core/platform/tests/bundles_networking_encryption_test.yaml
New test suite asserting: ENABLE_OVN_IPSEC absent when encryption is false or omitted; set when true for both variants; unset for isp-full-generic when false; deep-merge preserves existing kube-ovn overrides; nil-safe render when networking is null.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A toggle appears, east-west traffic in mind,
ENABLE_OVN_IPSEC — off by default, how kind!
🐇 When you flip it to true,
The Geneve gets encrypted too,
And tests confirm no nil pointer you'll find!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(platform): add opt-in in-cluster east-west encryption toggle' accurately summarizes the main change: introducing an opt-in toggle for east-west encryption at the platform level.
Linked Issues check ✅ Passed The PR satisfies issue #2977's acceptance criteria: it adds a platform-level opt-in toggle (networking.encryption.enabled) for the default kubeovn-cilium datapath defaulting to off, includes documentation of per-datapath scope and overhead, and clarifies that in-cluster encryption complements rather than replaces application-level TLS.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: template updates for KubeOVN IPsec toggle, new test suite for encryption configurations, and platform values documentation with no out-of-scope modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/networking-encryption

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added area/platform Issues or PRs related to platform infrastructure (bundle, flux, talos, installer) kind/feature Categorizes issue or PR as related to a new feature size/L This PR changes 100-499 lines, ignoring generated files labels Jun 22, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review June 22, 2026 22:29
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements an opt-in feature for in-cluster network encryption, providing a defense-in-depth layer for pod-to-pod traffic. By enabling IPsec for the KubeOVN Geneve overlay, the change secures inter-node communication without requiring application-level modifications. The implementation is designed to be backward compatible, off by default, and includes detailed documentation regarding its scope, performance implications, and limitations.

Highlights

  • In-cluster Encryption Toggle: Introduced a new configuration option networking.encryption.enabled in the platform chart to enable in-cluster east-west transport encryption.
  • KubeOVN IPsec Integration: Mapped the new toggle to KubeOVN's overlay IPsec (ENABLE_OVN_IPSEC), leveraging KubeOVN's native controller for certificate management via the Kubernetes CSR API.
  • Validation and Testing: Added comprehensive helm unittest coverage to ensure the toggle correctly handles various states and preserves existing KubeOVN overrides.
New Features

🧠 You can now enable Memory (public preview) to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces an opt-in east-west transport encryption feature (networking.encryption.enabled) for the platform's networking bundle, configuring KubeOVN to use Geneve-overlay IPsec (ENABLE_OVN_IPSEC) when enabled. Comprehensive test cases have been added to verify the bundle wiring and backward compatibility. The feedback requests running make generate to update values.schema.json with the new configuration property, ensuring proper input validation and dashboard UI integration.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +84 to +85
encryption:
enabled: false

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.

medium

Please run make generate to regenerate values.schema.json so that the new networking.encryption property is included in the schema. This is necessary for input validation and to expose the setting in the dashboard UI.

References
  1. values.schema.json is the JSON Schema for dashboard UI and input validation, and must be updated when values.yaml changes. (link)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I checked this against the package and there's nothing to regenerate here. packages/core/platform has no values.schema.json (no core/* package does), and its Makefile has no generate target, so make generate -C packages/core/platform errors rather than emitting a schema. The values.schema.json / cozyvalues-gen pipeline is for the user-facing catalog charts: the run-make-generate pre-commit hook iterates ./packages/apps/*/ and ./packages/extra/*/ only, never core/, and the repo-root make generate (codegen-drift) is scoped by its files: filter to the Go API paths. So no schema gate applies to this platform-chart change; the operator-facing docs for the new key live in the values.yaml comments. Leaving as-is.

@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as draft June 23, 2026 02:05

@myasnikovdaniil myasnikovdaniil 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.

LGTM — approving. Clean, purely-additive opt-in with the safety properties this kind of toggle needs.

Verified locally (render/static — did not enable IPsec on any live cluster):

  • Default-off is byte-identical to main. Rendered templates/bundles/system.yaml with the toggle absent on this branch vs main → zero diff, for isp-full. Existing installs are untouched.
  • On-delta is exactly the IPsec flag, deep-merged. Toggle on → the only change is func.ENABLE_OVN_IPSEC: true nested under kube-ovn, with the existing ipv4 overrides preserved (not replaced). Confirmed for both isp-full (kubeovn-cilium) and isp-full-generic (kubeovn-cilium-generic); no-op on isp-hosted/noop as documented.
  • Wiring is complete, not a dead flag. func.ENABLE_OVN_IPSEC is consumed by the vendored kube-ovn chart (--enable-ovn-ipsec on both controller and CNI daemonset, IPsec key-dir mount, runAsUser: 0), and the controller self-manages the IPsec CA + per-node certs via the K8s CSR API (RBAC for certificatesigningrequests approve/sign + kubeovn.io/signer present) — so the "no cert-manager wiring" claim holds.
  • Variant scoping in the values comments is accurate: the system bundle only selects kubeovn-cilium/kubeovn-cilium-generic/noop, so the Cilium-native and Kilo notes are correct. Kilo's meshGranularity: location default checks out.
  • helm unittest 66/66 pass (7 new), helm lint clean, core/platform is not cozyvalues-gen managed so no schema regen needed.

One optional hardening thought (non-blocking): enabling east-west IPsec on a running cluster is cluster-wide-disruptive (CNI rollout, ovs restart, effective-MTU drop) with no clean live disable. The values comment documents this well, so an operator flipping it via GitOps is informed. But this is exactly the class of change the proxyProtocol hazard guard a few lines down in the same file was built to gate. Worth considering whether a similar render-time acknowledgement (e.g. a networking.encryptionAcknowledgeDisruption: true confirm) is warranted, or whether the doc comment is sufficient given there's no hidden state asymmetry here (unlike proxyProtocol). Happy to merge as-is either way.

@lexfrei

Copy link
Copy Markdown
Contributor Author

Heads-up from testing this on a live Talos cluster: with ENABLE_OVN_IPSEC=true (what the networking.encryption.enabled toggle drives on the kubeovn-cilium datapath), the kube-ovn-cni pod fails to start on Talos nodes.

The IPsec path mounts a hostPath for the OVS IPsec keys at /etc/origin/ovs_ipsec_keys. On Talos /etc/origin is a read-only filesystem, so the kubelet can't create the directory:

failed to generate container spec: failed to apply OCI options: failed to mkdir "/etc/origin/ovs_ipsec_keys": mkdir /etc/origin: read-only file system

The container never starts (CreateContainerError), so no IPsec SAs establish (0 ESP SAs) and the overlay datapath is degraded on every Talos node. This affects the isp-full variant, which is the default/primary platform.

Static checks don't surface this — helm-unittest and chart review both pass, because the template renders correctly; the failure is a runtime hostPath-vs-read-only-rootfs issue specific to Talos that only appears on a live Talos node.

Fix direction: the IPsec keys path needs to be Talos-writable — a hostPath under /var (writable on Talos) or an emptyDir — rather than /etc/origin. Holding this in draft until that's addressed.

@lexfrei

Aleksei Sviridkin (lexfrei) commented Jul 16, 2026 •

Copy link
Copy Markdown
Contributor Author

Follow-up from the same Talos cluster, with the keys path fixed: the direction above was right and the knob exists. OVN_IPSEC_KEY_DIR is a kube-ovn value, and we already redirect its siblings (OPENVSWITCH_DIR, OVN_DIR) to /var/lib but never set the IPsec one, so it fell back to the read-only /etc/origin default. Setting OVN_IPSEC_KEY_DIR: /var/lib/ovs_ipsec_keys makes kube-ovn-cni start cleanly.

That half is really an upstream documentation gap, and I sent it there: the Talos sections of both kube-ovn charts list only two of the three host directories and leave the IPsec one at its /etc/origin default, so following the documented instructions and then enabling IPsec reproduces the error above. kubeovn/kube-ovn#7041 adds the missing directory to both sections, together with a render fix it turned up along the way — the ovs-ipsec-keys volume is indented one level too deep, which makes the v2 chart fail to render at all whenever enableOvnIpsec is set.

That unblocks container creation, but not the feature. With it applied IPsec does come up — 8 ESP SAs establish between node IPs in transport mode, and notably they establish with cilium.hostFirewall.enabled=true, so the host firewall does not block SA establishment. Two blockers remain, and both are why this stays in draft:

  1. Cross-node pod-to-pod traffic is 100% lost while IPsec is on. The SAs are up, but the encrypted datapath carries nothing. I have not isolated it further; the candidates are ESP (IP proto 50) dropped on the underlay, MTU/fragmentation, or a kube-ovn IPsec datapath bug on this setup. This is distinct from SA establishment, which demonstrably works.
  2. There is no clean teardown. Turning IPsec back off leaves stale xfrm SAs and policies behind — kube-ovn does not flush them on disable — so cross-node pod-to-pod stays broken after the rollback until ip xfrm state flush and ip xfrm policy flush are run by hand on every node. That makes the toggle a one-way door in practice.

So the blocker is neither the chart wiring nor the keys path — both are solved. It is that kube-ovn IPsec does not carry traffic on this datapath and cannot be turned off cleanly, which looks like an upstream problem rather than something this toggle can paper over. Unlike the keys path, these two are not reported upstream yet. I am keeping this in draft until the datapath and the teardown are fixed: shipping an opt-in that silently blackholes pod-to-pod traffic and cannot be reverted without manual surgery on every node is not worth the defense-in-depth.

@lexfrei
Aleksei Sviridkin (lexfrei) marked this pull request as ready for review July 27, 2026 19:46
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@dosubot dosubot Bot added the area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) label Jul 27, 2026
@lexfrei
Aleksei Sviridkin (lexfrei) merged commit 8bffa34 into main Jul 27, 2026
14 checks passed
@lexfrei
Aleksei Sviridkin (lexfrei) deleted the feat/networking-encryption branch July 27, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/networking Issues or PRs related to networking (ingress, gateway, vpn, metallb, kube-ovn) area/platform Issues or PRs related to platform infrastructure (bundle, flux, talos, installer) kind/feature Categorizes issue or PR as related to a new feature size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opt-in CNI transparent encryption for in-cluster (east-west) traffic

2 participants