Ways to find out how soon the AWS session expires?

Viewed 2428

Prerequisites

I have a script that works with AWS but does not deal with credentials explicitly. It just calls AWS API, expecting the credentials to be there according to default credentials provider chain. In fact, the wrapper that calls this script obtains temporary credentials and passes them in environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN).

Problem

The wrapper usually reuses existing credentials, and only asks to re-authenticate explicitly when they are about to expire. So there is a possibility that it passes credentials that have a few minutes left to live, which may not be enough, as the script execution usually takes long time. Unfortunately, I don't have control over the wrapper, so I would like to make the script check how much time it has left before making a decision whether to start or abort early to prevent failure in mid-flight.

AWS doesn't seem provide a standard way to query "how much time I have before my current session expires?" If I had control over the wrapper, I would make it pass the expiry date in an environment variable as well. I was hoping that AWS_SESSION_TOKEN is a sort of a JWT token, but unfortunately it is not, and does not seem to contain any timestamp in it.

Can anyone suggest any other ways around the given problem?

2 Answers

You probably need to check for the value of $AWS_SESSION_EXPIRATION

echo $AWS_SESSION_EXPIRATION

It should be giving you the expiration using the Zulu Time (Coordinated Universal Time) like below

2022-05-17T20:20:40Z

Then would need to compare the date on your system against it.

Instructions below work on macOS, for Linux you may have to modify the date function params

Let's check the current system time in Zulu Time:

date -u +'%Y-%m-%dT%H:%M:%SZ'

this should give something like the example:

2022-05-17T20:21:14Z

To automate things you can create a bash function to add to your ~/.bashrc or favorite terminal theme

aws_session_time_left() {
  zulu_time_now=$1

  aws_session_expiration_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $AWS_SESSION_EXPIRATION '+%s'`"
  zulu_time_now_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $zulu_time_now '+%s'`"

  if [[ $zulu_time_now < $AWS_SESSION_EXPIRATION ]]; then
    secs="`expr $aws_session_expiration_epoch - $zulu_time_now_epoch`"
    echo "+`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  else
    secs="`expr $zulu_time_now_epoch - $aws_session_expiration_epoch`"
    echo "-`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  fi
}

To consult the result of your function you can run:

aws_session_time_left "`date -u +'%Y-%m-%dT%H:%M:%SZ'`"

When your session is still active can give you something like:

+0h:56m:35s

or (when the session has expired) can give you how long since it expired:

-28h:13m:42s

NOTE the hours can be over 24h

BONUS: simplified standalone script version without parameters below

for example, you can also have as a standalone file get-aws-session-time-left.sh

#!/bin/bash

# Use to find out IF "aws session expiration" exist AND compare the current system time to IT
# These are the expected result types we want to have:
# - "no aws session found" (NOTE: this does not mean there is no aws session open in another terminal)
# - how long until the session expires (for example +0h:59m:45s)
# - how long since the session expired (for example -49h:41m:12s)
# NOTE: the hours do not reset at every 24 hours, we do not require to display the days
# IMPORTANT: the date function arguments work on macOS, for other OS types may need adapting

if [[ $AWS_SESSION_EXPIRATION != '' ]]; then
  zulu_time_now="`date -u +'%Y-%m-%dT%H:%M:%SZ'`" # TODO: see important note above

  aws_session_expiration_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $AWS_SESSION_EXPIRATION '+%s'`" # TODO: see important note above
  zulu_time_now_epoch="`date -j -u -f '%Y-%m-%dT%H:%M:%SZ' $zulu_time_now '+%s'`"                   # TODO: see important note above

  if [[ $zulu_time_now < $AWS_SESSION_EXPIRATION ]]; then
    secs="`expr $aws_session_expiration_epoch - $zulu_time_now_epoch`"
    echo "+`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  else
    secs="`expr $zulu_time_now_epoch - $aws_session_expiration_epoch`"
    echo "-`printf '%dh:%02dm:%02ds\n' $((secs/3600)) $((secs%3600/60)) $((secs%60))`"
  fi
else
  echo "no aws session found"
fi

Then to consult the AWS session expiration, you can just run:

bash get-aws-session-time-left.sh

you can use aws configure get to get the expiry time:

AWS_SESSION_EXPIRATION=$(aws configure get MYPROFILE.x_security_token_expires)

(obviously replace MYPROFILE with your profile name.)

Related