Skip to content

tls: backdate certificate NotBefore by 24 hours to tolerate clock skew#10591

Open
sdodson wants to merge 1 commit into
openshift:mainfrom
sdodson:tls-notbefore-backdate
Open

tls: backdate certificate NotBefore by 24 hours to tolerate clock skew#10591
sdodson wants to merge 1 commit into
openshift:mainfrom
sdodson:tls-notbefore-backdate

Conversation

@sdodson
Copy link
Copy Markdown
Member

@sdodson sdodson commented Jun 2, 2026

Problem

When a VM's hardware clock (RTC) stores local time but the OS has no configuration telling it so, Linux reads the hwclock assuming UTC. The resulting system clock is offset behind true UTC by the host's timezone difference—up to several hours—until NTP corrects it.

The certificate's NotBefore is a correct UTC timestamp, but from the VM's skewed perspective it appears to be in the future, so TLS handshakes fail during bootstrap with "certificate not yet valid".

Change

Set NotBefore to time.Now() - 24h in the two places where self-signed certificates are created:

  • pkg/asset/tls/tls.goSelfSignedCertificate
  • pkg/asset/imagebased/configimage/ingressoperatorsigner.goselfSignedCertificate

NotAfter is left unchanged, so the validity window simply shifts: it starts 24 hours earlier and ends at the originally intended expiry time. This tolerates a VM clock up to 24 hours behind true UTC.

SignedCertificate already inherits NotBefore from its signing CA (caCert.NotBefore), so certificates in that path pick up the change automatically with no additional modifications needed.

Testing

  • go build ./pkg/asset/tls/... ./pkg/asset/imagebased/configimage/... passes cleanly.

VMs can boot with their hardware clock set to local time rather than UTC.
On a host in UTC-5, that means the system clock reads five hours behind
UTC at boot, before NTP has a chance to correct it.  Any certificate
whose NotBefore equals the wall-clock time of generation will appear
"not yet valid" to that VM for up to five hours, blocking TLS handshakes
during bootstrap.

Setting NotBefore to time.Now()-24h ensures the certificate is already
valid on any host whose clock is up to 24 hours behind the generator's
clock.  NotAfter is unchanged, so the effective validity window simply
shifts: it starts 24 hours earlier and ends at the originally intended
expiry time.

SelfSignedCertificate and the image-based ingress operator signer both
set NotBefore directly; signed certificates already inherit NotBefore
from their signing CA, so they pick up the change automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Walkthrough

This PR adjusts the validity window of self-signed certificates by backdating their NotBefore field by 24 hours across two certificate generation implementations in the TLS and ingress operator signer modules.

Changes

Certificate validity backdate

Layer / File(s) Summary
Backdate certificate NotBefore to 24 hours past
pkg/asset/tls/tls.go, pkg/asset/imagebased/configimage/ingressoperatorsigner.go
SelfSignedCertificate and selfSignedCertificate now set NotBefore to time.Now().Add(-24 * time.Hour) instead of time.Now(), extending the backward validity window by 24 hours.

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: backdating certificate NotBefore by 24 hours to tolerate clock skew, which directly matches the changeset's core modification to two TLS certificate generation functions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.
Stable And Deterministic Test Names ✅ Passed PR modifies only TLS certificate generation logic in two production files; no test files or Ginkgo test names are added/modified, so the check is not applicable.
Test Structure And Quality ✅ Passed Custom check is not applicable: PR tests use standard Go testing (testing.T), not Ginkgo framework.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests are added in this PR. The changes only modify certificate generation logic by backdating NotBefore by 24 hours. The check is not applicable to non-test code changes.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR modifies certificate generation code only; no new Ginkgo e2e tests were added. SNO compatibility check is not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed PR only modifies TLS certificate generation utilities (NotBefore timestamp), not deployment manifests or scheduling constraints. Check is not applicable to this codebase change.
Ote Binary Stdout Contract ✅ Passed PR only modifies certificate NotBefore timestamp from time.Now() to time.Now().Add(-24*time.Hour) in utility functions; no new stdout writes in process-level code were introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added. Changes are to TLS certificate generation utility functions only, not test code.
No-Weak-Crypto ✅ Passed PR only changes certificate NotBefore times (+24hr offset for clock skew); no weak cryptographic algorithms, custom crypto, or token comparisons introduced.
Container-Privileges ✅ Passed PR modifies only Go source files for TLS certificate generation; no Kubernetes manifests, Docker configurations, or container specs containing privileged settings were changed.
No-Sensitive-Data-In-Logs ✅ Passed PR changes only affect certificate NotBefore timestamp (adds 24-hour backdate). No new logging is introduced, and existing error logs only contain generic error messages without sensitive data.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot requested review from eranco74 and patrickdillon June 2, 2026 14:33
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 2, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign sadasu for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@patrickdillon
Copy link
Copy Markdown
Contributor

@sdodson is there a bug for this? if not, we can use no-jira, but curious about context.

@sdodson
Copy link
Copy Markdown
Member Author

sdodson commented Jun 2, 2026

@sdodson is there a bug for this? if not, we can use no-jira, but curious about context.

Not yet, I was mainly interested in using this to start the discussion on Slack. I'd assumed that there was some reasoning why we hadn't done this yet. I can open a bug once we agree we should, I'm not sure given this has been a problem since day 1 that we'd bother backporting but that would at least allow us to do so.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Jun 2, 2026

@sdodson: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants