Skip to content

rotator: stop exiting process on secret refresh#491

Open
sozercan wants to merge 1 commit intomasterfrom
codex/fix-restart-loop-dos-vulnerability
Open

rotator: stop exiting process on secret refresh#491
sozercan wants to merge 1 commit intomasterfrom
codex/fix-restart-loop-dos-vulnerability

Conversation

@sozercan
Copy link
Copy Markdown
Member

@sozercan sozercan commented Apr 9, 2026

Motivation

  • The RestartOnSecretRefresh option caused the process to call os.Exit(0) inside refreshCertIfNeeded, enabling a Secret writer to repeatedly trigger restarts (availability DoS); the change prevents accidental restart loops while preserving API compatibility.

Description

  • Remove the forced os.Exit(0) calls in refreshCertIfNeeded and replace them with a deprecation/no-op log so certificate refreshes no longer terminate the process while still accepting the RestartOnSecretRefresh field for compatibility.

Testing

  • Attempted to run go test ./pkg/rotator and go test -run TestDoesNotExist -count=1 ./pkg/rotator, but tests could not complete in this environment because kubebuilder test assets (for example /usr/local/kubebuilder/bin/etcd) are missing, so no automated test results are available.

Codex Task

Copilot AI review requested due to automatic review settings April 9, 2026 19:38
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

This PR updates the cert rotator to prevent the process from terminating when certificate Secrets are refreshed, eliminating a restart-loop/availability DoS risk while keeping the RestartOnSecretRefresh option accepted for compatibility.

Changes:

  • Removed os.Exit(0) from refreshCertIfNeeded when RestartOnSecretRefresh is enabled.
  • Replaced forced-exit behavior with a deprecation/no-op informational log.
Show a summary per file
File Description
pkg/rotator/rotator.go Stops exiting the process on Secret refresh and logs that RestartOnSecretRefresh is deprecated/ignored.

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 thread pkg/rotator/rotator.go
Comment on lines 341 to 343
if cr.RestartOnSecretRefresh {
crLog.Info("Secrets have been updated; exiting so pod can be restarted (This behaviour can be changed with the option RestartOnSecretRefresh)")
os.Exit(0)
crLog.Info("Secrets have been updated; RestartOnSecretRefresh is deprecated and ignored to avoid restart loops")
}
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.

RestartOnSecretRefresh is now effectively a no-op but the only signal to callers is a runtime log. Since this is an exported field, consider adding a GoDoc deprecation marker (e.g., a Deprecated: comment on the field or type) so API consumers and linters can detect the deprecation without relying on logs.

Copilot uses AI. Check for mistakes.
Comment thread pkg/rotator/rotator.go
Comment on lines 341 to 356
@@ -353,8 +352,7 @@ func (cr *CertRotator) refreshCertIfNeeded() (bool, error) {
}
crLog.Info("server certs refreshed")
if cr.RestartOnSecretRefresh {
crLog.Info("Secrets have been updated; exiting so pod can be restarted (This behaviour can be changed with the option RestartOnSecretRefresh)")
os.Exit(0)
crLog.Info("Secrets have been updated; RestartOnSecretRefresh is deprecated and ignored to avoid restart loops")
}
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 same deprecation log message is duplicated in both refresh paths. Consider extracting the message (const or small helper) to avoid future divergence and make it easier to update/translate consistently.

Copilot uses AI. Check for mistakes.
Comment thread pkg/rotator/rotator.go
Comment on lines 339 to 344
rotatedCA = true
crLog.Info("server certs refreshed")
if cr.RestartOnSecretRefresh {
crLog.Info("Secrets have been updated; exiting so pod can be restarted (This behaviour can be changed with the option RestartOnSecretRefresh)")
os.Exit(0)
crLog.Info("Secrets have been updated; RestartOnSecretRefresh is deprecated and ignored to avoid restart loops")
}
return true, nil
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.

There are existing rotator tests, but none cover the RestartOnSecretRefresh behavior. Adding a unit/integration test that sets RestartOnSecretRefresh: true and triggers a cert refresh would guard against regressions (e.g., reintroducing process termination) and validate the new no-op semantics.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@JaydipGabani JaydipGabani left a comment

Choose a reason for hiding this comment

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

This is not something we want to do, this os.Exit is intentional and is dependent on the cert-controller setup.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
@sozercan sozercan force-pushed the codex/fix-restart-loop-dos-vulnerability branch from ed5ce6c to a266146 Compare April 21, 2026 21:07
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.

3 participants