Skip to content

Require leader election for CertRotator and webhook cache#490

Open
sozercan wants to merge 1 commit intomasterfrom
codex/fix-leader-election-behavior-in-cert-rotator
Open

Require leader election for CertRotator and webhook cache#490
sozercan wants to merge 1 commit intomasterfrom
codex/fix-leader-election-behavior-in-cert-rotator

Conversation

@sozercan
Copy link
Copy Markdown
Member

@sozercan sozercan commented Apr 9, 2026

Motivation

  • The repo introduced a regression where CertRotator and its webhook reconciler defaulted to opt-in leader election via the zero-value RequireLeaderElection=false, which allowed multiple replicas to concurrently rotate certificates and inject CA bundles causing webhook TLS churn and availability risk.
  • The change restores the previous safety posture by ensuring the rotator and related controller pieces participate in leader election by default while preserving the existing field for compatibility.

Description

  • Set ReconcileWH.needLeaderElection to true when constructing the reconciler in AddRotator so the webhook reconciler always requires leader election.
  • Register the namespaced cacheWrapper with needLeaderElection: true in addNamespacedCache so the cache startup is gated by leader election.
  • Mark the CertRotator.RequireLeaderElection field as deprecated/ignored and make CertRotator.NeedLeaderElection() return true unconditionally to force leader-election participation.
  • The code keeps the RequireLeaderElection field for API/backwards-compatibility but prevents the unsafe zero-value behavior.

Testing

  • Ran go test ./pkg/rotator/... with a 25s timeout in the environment which timed out and returned EXIT:124, so tests could not be completed successfully in this environment.
  • A local commit was created with the fix and the change is limited and minimal to reduce regression risk.

Codex Task

Copilot AI review requested due to automatic review settings April 9, 2026 19:14
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Restores a safer default for certificate rotation by ensuring the CertRotator, its webhook reconciler/controller, and the namespaced cache only run when the manager is leader-elected (preventing concurrent rotations across replicas when leader election is enabled).

Changes:

  • Force ReconcileWH.needLeaderElection to true when wiring the rotator (AddRotator).
  • Register the namespaced cache wrapper with needLeaderElection: true so its startup is gated by leader election.
  • Deprecate/ignore CertRotator.RequireLeaderElection and make CertRotator.NeedLeaderElection() always return true.
Show a summary per file
File Description
pkg/rotator/rotator.go Forces leader-election participation for the rotator, webhook controller, and namespaced cache to avoid multi-replica certificate rotation/injection churn.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 1/1 changed files
  • Comments generated: 3

Comment on lines +211 to 213
// Wrapping the cache so the manager can gate startup on leader election.
if err := mgr.Add(&cacheWrapper{Cache: c, needLeaderElection: true}); err != nil {
return nil, fmt.Errorf("registering namespaced cache: %w", err)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

After hardcoding needLeaderElection: true, the cr *CertRotator parameter is no longer used in addNamespacedCache, which will cause a Go compile error (cr declared but not used). Consider removing the cr parameter from addNamespacedCache (and updating its call sites) or renaming it to _ if you need to keep the signature temporarily.

Copilot uses AI. Check for mistakes.
ExtKeyUsages *[]x509.ExtKeyUsage
// RequireLeaderElection should be set to true if the CertRotator needs to
// be run in the leader election mode.
// RequireLeaderElection is deprecated and ignored.
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

The field is described as deprecated, but the doc comment won’t be recognized by Go tooling unless it uses the canonical Deprecated: form. Consider changing the comment to start with // Deprecated: so go doc and linters surface the deprecation correctly.

Suggested change
// RequireLeaderElection is deprecated and ignored.
// Deprecated: RequireLeaderElection is ignored.

Copilot uses AI. Check for mistakes.
Comment on lines 274 to 276
func (cr *CertRotator) NeedLeaderElection() bool {
return cr.RequireLeaderElection
return true
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

Leader-election behavior is being changed here (the rotator now always returns true). Given pkg/rotator already has a substantial test suite, it would be good to add a unit test that asserts NeedLeaderElection() is true regardless of RequireLeaderElection’s value, to prevent regressions back to the unsafe default.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants