Verify AWS Credentials with boto3

You can make a call by directly specifying credentials:

import boto3

client = boto3.client('s3', aws_access_key_id='xxx', aws_secret_access_key='xxx')
response = client.list_buckets()

You can then use the response to determine whether the credentials are valid.

However, it is possible that a user has valid credentials, but does not have permission to call list_buckets(). This might make it harder to determine whether they have valid credentials. You'll need to try various combinations to see what response is sent back to your code.


Such a credential-validating method does exist; it's the STS GetCallerIdentity API call (boto3 method docs).

With expired temporary credentials:

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jantman/venv/lib/python3.8/site-packages/botocore/client.py", line 276, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/jantman/venv/lib/python3.8/site-packages/botocore/client.py", line 586, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (ExpiredToken) when calling the GetCallerIdentity operation: The security token included in the request is expired

With invalid credentials:

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jantman/venvs/current/lib/python3.8/site-packages/botocore/client.py", line 316, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/jantman/venvs/current/lib/python3.8/site-packages/botocore/client.py", line 626, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid

With valid credentials (IDs replaced with X's):

>>> import boto3
>>> sts = boto3.client('sts')
>>> sts.get_caller_identity()
{'UserId': 'AROAXXXXXXXXXXXXX:XXXXXXX', 'Account': 'XXXXXXXXXXXX', 'Arn': 'arn:aws:sts::XXXXXXXXXXXX:assumed-role/Admin/JANTMAN', 'ResponseMetadata': {'RequestId': 'f44ec1d9-XXXX-XXXX-XXXX-a26c85be1c60', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'f44ec1d9-XXXX-XXXX-XXXX-a26c85be1c60', 'content-type': 'text/xml', 'content-length': '426', 'date': 'Thu, 28 May 2020 10:45:36 GMT'}, 'RetryAttempts': 0}}

Invalid credentials will raise an exception and valid credentials won't, so you can do something such as:

import boto3
sts = boto3.client('sts')
try:
    sts.get_caller_identity()
    print("Credentials are valid.")
except boto3.exceptions.ClientError:
    print("Credentials are NOT valid.")