@@ -23,7 +23,7 @@ use std::fmt;
23
23
use std:: sync:: { Arc , RwLock } ;
24
24
use std:: time:: { Duration , SystemTime } ;
25
25
26
- const CREDENTIAL_EXPIRATION_INTERVAL : Duration = Duration :: from_secs ( 15 * 60 ) ;
26
+ const CREDENTIAL_EXPIRATION_INTERVAL : Duration = Duration :: from_secs ( 10 * 60 ) ;
27
27
28
28
#[ derive( Debug ) ]
29
29
struct ImdsCommunicationError {
@@ -192,21 +192,20 @@ impl ImdsCredentialsProvider {
192
192
//
193
193
// This allows continued use of the credentials even when IMDS returns expired ones.
194
194
fn maybe_extend_expiration ( & self , expiration : SystemTime ) -> SystemTime {
195
+ let now = self . time_source . now ( ) ;
196
+ // If credentials from IMDS are not stale, use them as they are.
197
+ if now < expiration {
198
+ return expiration;
199
+ }
200
+
195
201
let rng = fastrand:: Rng :: with_seed (
196
- self . time_source
197
- . now ( )
198
- . duration_since ( SystemTime :: UNIX_EPOCH )
202
+ now. duration_since ( SystemTime :: UNIX_EPOCH )
199
203
. expect ( "now should be after UNIX EPOCH" )
200
204
. as_secs ( ) ,
201
205
) ;
202
206
// calculate credentials' refresh offset with jitter
203
- let refresh_offset =
204
- CREDENTIAL_EXPIRATION_INTERVAL + Duration :: from_secs ( rng. u64 ( 120 ..=600 ) ) ;
205
- let new_expiry = self . time_source . now ( ) + refresh_offset;
206
-
207
- if new_expiry < expiration {
208
- return expiration;
209
- }
207
+ let refresh_offset = CREDENTIAL_EXPIRATION_INTERVAL + Duration :: from_secs ( rng. u64 ( 0 ..=300 ) ) ;
208
+ let new_expiry = now + refresh_offset;
210
209
211
210
tracing:: warn!(
212
211
"Attempting credential expiration extension due to a credential service availability issue. \
@@ -342,6 +341,53 @@ mod test {
342
341
connection. assert_requests_match ( & [ ] ) ;
343
342
}
344
343
344
+ #[ tokio:: test]
345
+ #[ traced_test]
346
+ async fn credentials_not_stale_should_be_used_as_they_are ( ) {
347
+ let connection = TestConnection :: new ( vec ! [
348
+ (
349
+ token_request( "http://169.254.169.254" , 21600 ) ,
350
+ token_response( 21600 , TOKEN_A ) ,
351
+ ) ,
352
+ (
353
+ imds_request( "http://169.254.169.254/latest/meta-data/iam/security-credentials/" , TOKEN_A ) ,
354
+ imds_response( r#"profile-name"# ) ,
355
+ ) ,
356
+ (
357
+ imds_request( "http://169.254.169.254/latest/meta-data/iam/security-credentials/profile-name" , TOKEN_A ) ,
358
+ imds_response( "{\n \" Code\" : \" Success\" ,\n \" LastUpdated\" : \" 2021-09-20T21:42:26Z\" ,\n \" Type\" : \" AWS-HMAC\" ,\n \" AccessKeyId\" : \" ASIARTEST\" ,\n \" SecretAccessKey\" : \" testsecret\" ,\n \" Token\" : \" testtoken\" ,\n \" Expiration\" : \" 2021-09-21T04:16:53Z\" \n }" ) ,
359
+ ) ,
360
+ ] ) ;
361
+
362
+ // set to 2021-09-21T04:16:50Z that makes returned credentials' expiry (2021-09-21T04:16:53Z)
363
+ // not stale
364
+ let time_of_request_to_fetch_credentials = UNIX_EPOCH + Duration :: from_secs ( 1632197810 ) ;
365
+ let time_source = TimeSource :: testing ( & TestingTimeSource :: new (
366
+ time_of_request_to_fetch_credentials,
367
+ ) ) ;
368
+
369
+ tokio:: time:: pause ( ) ;
370
+
371
+ let provider_config = ProviderConfig :: no_configuration ( )
372
+ . with_http_connector ( DynConnector :: new ( connection. clone ( ) ) )
373
+ . with_time_source ( time_source)
374
+ . with_sleep ( TokioSleep :: new ( ) ) ;
375
+ let client = crate :: imds:: Client :: builder ( )
376
+ . configure ( & provider_config)
377
+ . build ( )
378
+ . await
379
+ . expect ( "valid client" ) ;
380
+ let provider = ImdsCredentialsProvider :: builder ( )
381
+ . configure ( & provider_config)
382
+ . imds_client ( client)
383
+ . build ( ) ;
384
+ let creds = provider. provide_credentials ( ) . await . expect ( "valid creds" ) ;
385
+ assert ! ( creds. expiry( ) . unwrap( ) > time_of_request_to_fetch_credentials) ;
386
+ connection. assert_requests_match ( & [ ] ) ;
387
+
388
+ // There should not be logs indicating credentials are extended for stability.
389
+ assert ! ( !logs_contain( "Attempting credential expiration extension" ) ) ;
390
+ }
345
391
#[ tokio:: test]
346
392
#[ traced_test]
347
393
async fn expired_credentials_should_be_extended ( ) {
0 commit comments