@@ -38,26 +38,30 @@ use crate::{
3838
3939mod cert_resolver;
4040
41- pub const WEBHOOK_CA_LIFETIME : Duration = Duration :: from_hours_unchecked ( 24 ) ;
42-
43- /// The wall-clock lifetime of generated webhook certificates. If this is ever
44- /// reduced, ensure it stays well above [`CERTIFICATE_ROTATION_CHECK_INTERVAL`]
41+ /// All certificates (CAs and leaf certificates) are valid for this amount of time in hours. If this
42+ /// is ever reduced, ensure it stays well above [`CERTIFICATE_ROTATION_CHECK_INTERVAL`]
4543/// (currently 5 minutes), otherwise the certificate could expire between checks.
46- const WEBHOOK_CERTIFICATE_LIFETIME_HOURS : u64 = 24 ;
44+ const CERTIFICATE_LIFETIME_HOURS : u64 = 24 ;
45+
46+ /// The CA lifetime as a human-readable [`Duration`].
47+ pub const WEBHOOK_CA_LIFETIME : Duration =
48+ Duration :: from_hours_unchecked ( CERTIFICATE_LIFETIME_HOURS ) ;
49+
50+ /// The leaf certificate lifetime as a human-readable [`Duration`].
4751pub const WEBHOOK_CERTIFICATE_LIFETIME : Duration =
48- Duration :: from_hours_unchecked ( WEBHOOK_CERTIFICATE_LIFETIME_HOURS ) ;
52+ Duration :: from_hours_unchecked ( CERTIFICATE_LIFETIME_HOURS ) ;
4953
50- /// How often to check whether the certificate needs rotation. This is
51- /// intentionally independent of the certificate lifetime — it controls how
52- /// quickly we detect wall-clock drift (from hibernation, VM migration, etc.),
53- /// not how long the certificate lives.
54- const CERTIFICATE_ROTATION_CHECK_INTERVAL : Duration = Duration :: from_minutes_unchecked ( 5 ) ;
54+ /// Rotate the certificate when less than 1/6 of its lifetime remains (4 hours for the current 24h
55+ /// lifetime). Derived from [`CERTIFICATE_LIFETIME_HOURS`] so it scales if the lifetime changes.
56+ const CERTIFICATE_EXPIRY_BUFFER_HOURS : u64 = CERTIFICATE_LIFETIME_HOURS * 60 / 6 ;
5557
56- /// Rotate the certificate when less than 1/6 of its lifetime remains
57- /// (4 hours for the current 24h lifetime). Derived from
58- /// [`WEBHOOK_CERTIFICATE_LIFETIME`] so it scales if the lifetime changes.
5958const CERTIFICATE_EXPIRY_BUFFER : Duration =
60- Duration :: from_minutes_unchecked ( WEBHOOK_CERTIFICATE_LIFETIME_HOURS * 60 / 6 ) ;
59+ Duration :: from_minutes_unchecked ( CERTIFICATE_EXPIRY_BUFFER_HOURS ) ;
60+
61+ /// How often to check whether the certificate needs rotation. This is intentionally independent of
62+ /// the certificate lifetime - it controls how quickly we detect wall-clock drift (from hibernation,
63+ /// VM migration, etc.), not how long the certificate lives.
64+ const CERTIFICATE_ROTATION_CHECK_INTERVAL : Duration = Duration :: from_minutes_unchecked ( 5 ) ;
6165
6266pub type Result < T , E = TlsServerError > = std:: result:: Result < T , E > ;
6367
@@ -170,12 +174,9 @@ impl TlsServer {
170174 router,
171175 } = self ;
172176
173- // Periodically check whether the certificate needs rotation based on
174- // wall-clock time. This avoids the monotonic vs wall-clock drift problem
175- // that can occur during hibernation, VM migration, or cgroup freezing.
176- let check_start = tokio:: time:: Instant :: now ( ) + * CERTIFICATE_ROTATION_CHECK_INTERVAL ;
177- let mut rotation_check =
178- tokio:: time:: interval_at ( check_start, * CERTIFICATE_ROTATION_CHECK_INTERVAL ) ;
177+ let start = tokio:: time:: Instant :: now ( ) + * CERTIFICATE_ROTATION_CHECK_INTERVAL ;
178+ let mut rotation_check_interval =
179+ tokio:: time:: interval_at ( start, * CERTIFICATE_ROTATION_CHECK_INTERVAL ) ;
179180
180181 let tls_acceptor = TlsAcceptor :: from ( Arc :: new ( config) ) ;
181182 let tcp_listener = TcpListener :: bind ( socket_addr)
@@ -220,7 +221,7 @@ impl TlsServer {
220221
221222 // Check wall-clock time to decide if the certificate needs rotation.
222223 // This is cancellation-safe: if cancelled, the tick is NOT consumed.
223- _ = rotation_check . tick( ) => {
224+ _ = rotation_check_interval . tick( ) => {
224225 if cert_resolver. needs_rotation( * CERTIFICATE_EXPIRY_BUFFER ) {
225226 tracing:: info!( "certificate approaching expiry, rotating" ) ;
226227 cert_resolver
0 commit comments