InvalidClientTokenId exception while validating AccessKeyId

0

Hi Everyone,

I am using Python boto3 libraries to create STS Temporary tokens. I am storing the Access Key ID, Secret Access Key, Session token in default credentials file. This piece works fine.

I am trying to validate, whether the token has expired, before creating a new token. boto3.get_access_key_info() (Ref: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html#STS.Client.get_access_key_info ) seems validates the token ID and returns the account number.

However, get_access_key_info() method always throwing exception InvalidClientTokenId, even if the Access Key ID is valid.

Below is my code -

session = boto3.session.Session(profile_name='saml')
client = boto3.client('sts')
try:
print ('Validating Profile: {0} | AccessKeyId: {1}'.format('saml', session.get_credentials().access_key))
accessKeyId = session.get_credentials().access_key
accKeyChkResp = client.get_access_key_info(AccessKeyId=accessKeyId)
return True
except Exception as e:
print(Fore.LIGHTRED_EX + 'Code: {0} | Profile Name: {1} | Exception: {2!r}'.format(e.response['Error']['Code'], awsProfileName, e.args))
return False

Error:
Code: InvalidClientTokenId | Profile Name: saml | Exception: ('An error occurred (InvalidClientTokenId) when calling the GetAccessKeyInfo operation: The security token included in the request is invalid.',)

Please let me know, if there is any solution to this issue.

asked 5 years ago2190 views
4 Answers
0

Hi,
I ran the following code in my test environment, and it worked fine. It printed out the account number for the access key, and it gave an error when no associated account exists.

import boto3
import json
session = boto3.session.Session(profile_name='saml')
client = boto3.client('sts')
try:
  print ('Validating Profile: {0} | AccessKeyId: {1}'.format('saml', session.get_credentials().access_key))
  accessKeyId = session.get_credentials().access_key
  accKeyChkResp = client.get_access_key_info(AccessKeyId=accessKeyId)
  print(json.dumps(accKeyChkResp))

except Exception as e:
  print(Fore.LIGHTRED_EX + 'Code: {0} | Profile Name: {1} | Exception: {2!r}'.format(e.response, awsProfileName, e.args))

However, this piece of code does NOT provide the information that you are looking for

This operation does not indicate the state of the access key. The key might be active, inactive, or deleted. Active keys might not have permissions to perform an operation. Providing a deleted access key might return an error that the key doesn't exist.

Link: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts.html#STS.Client.get_access_key_info

Also, this is discussed a bit in this stackoverflow post.. Where they discuss that this capability does NOT currently exist and if it did exist, it might be considered a security risk. Also, they discuss work-arounds where you could do a list-buckets() call to see if the Key works.. but that would only be workable if all possible Keys have the list-buckets() permissions.
Link: https://stackoverflow.com/questions/53548737/verify-aws-credentials-with-boto3

it may be a good to have feature, but it may lead to security risks. If a such a method would exist, it may lead to better recon for an adversary, should the adversary find a pair of creds. –

Hope this helps.
-randy

answered 5 years ago
0

Hi Randy,

Are you using Temporary Access Keys? Can you please check, if keys (starting with ASIA*) received through assume_role_with_saml works.

Thanks,
Indranil

answered 5 years ago
0

My bad!! While creating the client, I should have referred the session context, rather than boto3.

It should be -

session = boto3.session.Session(profile_name='saml')
client = *session*.client('sts')

Not

session = boto3.session.Session(profile_name='saml')
client = _boto3_.client('sts')

Thanks for your help.

answered 5 years ago
0

My bad!! While creating the client, I should have referred the session context, rather than boto3.

It should be -
session = boto3.session.Session(profile_name='saml')
client = session.client('sts')

Not
session = boto3.session.Session(profile_name='saml')
client = boto3.client('sts')

Thanks for your help.

answered 5 years ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions