52

I am struggling to find out how I can get my aws_access_key_id and aws_secret_access_key dynamically from my code.

In boto2 I could do the following: boto.config.get_value('Credentials', 'aws_secret_access_key') but I can't seem to find a similar method in boto3. I was able to find the keys if I look in boto3.Session()._session._credentials but that seems like the mother of all hacks to me and I would rather not go down that road.

tedder42
  • 23,519
  • 13
  • 86
  • 102
Mo.
  • 40,243
  • 37
  • 86
  • 131
  • Could you clarify why you need direct access to the credentials in your code? – Mark B Mar 29 '16 at 15:30
  • 1
    I need it because I copy data from S3 to Redshift and so I need the `aws_access_key_id` and `aws_secret_access_key`. I would rather not have to write code which goes in to the config/credential files and find them out when Boto already does this. – Mo. Mar 29 '16 at 15:35
  • Yeah, passing those keys to Redshift for S3 access is a major pain. I wish they would allow us to assign an IAM role to Redshift to avoid the need to do that. I'd be worried that your solution isn't going to work on an EC2 instance using an IAM instance profile, or in an Lambda function. – Mark B Mar 29 '16 at 15:41
  • @Mo. I agree with MarkB. It is not a portable solution. Check my solution and see it works. – helloV Mar 29 '16 at 18:58
  • How about put the key inside the credential config and give it a new profile name other than [default] ? And use profile_name= point to explicit profile key? – mootmoot Mar 30 '16 at 11:10
  • By the way, you don't have to do this for Redshift COPY commands anymore. Redshift can assume IAM roles now: https://aws.amazon.com/releasenotes/8869404215180370 That's the better solution. – Mark B Mar 30 '16 at 13:55

4 Answers4

79

It's generally a best practice to only use temporary credentials. You can get temporary credentials with STS.get_session_token.

EDIT: As of this PR, you can access the current session credentials like so:

import boto3

session = boto3.Session()
credentials = session.get_credentials()

# Credentials are refreshable, so accessing your access key / secret key
# separately can lead to a race condition. Use this to get an actual matched
# set.
credentials = credentials.get_frozen_credentials()
access_key = credentials.access_key
secret_key = credentials.secret_key

redshift = session.client('redshift')
...

I would still recommend using temporary credentials scoped to exactly what redshift needs.

Jordon Phillips
  • 14,963
  • 4
  • 35
  • 42
  • 7
    Hi @Jordon Phillips, if we use `get_frozen_credentials()` will the tokens expire again ? or will it keep on working without needing to refresh token anymore? – Manish Kakati Jan 04 '20 at 07:09
  • This also seems to work fetching temporary credentials (derived from a K8S service account from OIDC with an IAM role affiliation). – CoatedMoose Jul 20 '23 at 23:25
24

Use botocore

>>> import botocore.session
>>> session = botocore.session.get_session()

>>> session.get_credentials().access_key
'AKIAABCDEF6RWSGI234Q'

>>> session.get_credentials().secret_key
'abcdefghijkl+123456789+qbcd'

>>> session.get_config_variable('region')
'us-east-1'
helloV
  • 50,176
  • 7
  • 137
  • 145
  • are these programatic access keys of IAM ? without ARN how these are generating, could you please explain – sudhir tataraju Apr 09 '19 at 06:17
  • @sudhirtataraju Boto can get the keys in one of many ways. The code shows how to retrieve the keys as Boto sees it. For example, when you supply the credentials and Boto gives access errors. You may want to confirm whether the credentials that you passed is same as what Boto uses. See: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html – helloV Apr 09 '19 at 06:23
10

Can I suggest that accessing the keys is WRONG using boto3:

import boto3
session = boto3.Session(profile_name="my-profile")

dynamodb = session.resource(
    "dynamodb",
    region_name=session.region_name,
    # aws_access_key_id=session.get_credentials().access_key,
    # aws_secret_access_key=session.get_credentials().secret_key,
)

Notice, I commented out accessing the keys because 1:

Any clients created from this session will use credentials from the [my-profile] section of ~/.aws/credentials.

jakebrinkmann
  • 704
  • 9
  • 23
  • 1
    Nice, this was exactly what I needed. Thank you. – Jeshizaemon Mar 05 '21 at 00:35
  • There are use-cases where it's useful to have the keys for use outside boto3. An example would be if you wanted to pass credentials to a process that for some reason (older SDK maybe) couldn't access the credentials itself. – Rory Browne Apr 06 '23 at 13:05
0
import boto3
from botocore import session

def get_credentials():
   credentials = boto3.client(
       'sts',
       region_name="us-east-1", 
       aws_access_key_id='123', 
       aws_secret_access_key='123',
   ).assume_role(
       RoleArn="arn:aws-cn:iam::123",  # Your RoleArn
       RoleSessionName='boto3_client')

   return credentials


def db_conn():
    credentials = get_credentials()

    db = boto3.resource(
        'dynamodb',
        region_name="us-east-1",
        aws_access_key_id=credentials['Credentials']['AccessKeyId'],
        aws_secret_access_key=credentials['Credentials']['SecretAccessKey'],
        aws_session_token=credentials['Credentials']['SessionToken'],
    )
   
    # table = db.Table(your_table_name)

    # response = table.query(
    # IndexName='age',
    # KeyConditionExpression=Key('age').eq(11)
    # )


if __name__ == "__main__": 
   db_conn()



Topaz
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 13 '22 at 06:50