aws / amazon-redshift-python-driver

Redshift Python Connector. It supports Python Database API Specification v2.0.
Apache License 2.0
202 stars 72 forks source link

Support inline role_arn for IAM Role authentication #225

Open Fleid opened 3 weeks ago

Fleid commented 3 weeks ago

See this issue for context : https://github.com/dbt-labs/dbt-redshift/issues/842

The connector need to be able to support IAM Role via inline parameters in addition to via an AWS profile, the same way it does for IAM Users.

If I open a connection with role_arn, source_access_key_id, and source_secret_access_key, currently it ignores role_arn and uses the access key to open an IAM user connection. What I need instead is to leverage the access key to assume the role - see boto3 credentials, we're in the assume role provider chapter, particularly:

If MFA authentication is not enabled then you only need to specify a role_arn and a source_profile.

What I need is to pass all the parameters inline, not a source_profile.

Brooke-white commented 6 days ago

Hi @Fleid , thank you for reaching out with this feature request. redshift-connector's role_arn parameter is specific to JwtCredentialsProvider, which is why you're seeing it ignored.

What I need is to pass all the parameters inline, not a source_profile.

Boto3 does not support this functionality at this time, but they have a long running issue, https://github.com/boto/botocore/issues/761, which tracks this feature request.

As such, the recommendation from the boto3 side is to take the following approach:

  1. creating a session with your inline credentials
  2. creating a sts client
  3. calling assume_role on the sts client, passing in your role_arn
  4. retrieving the temporary aws credentials from the response payload from the call to assume_role

at this point, the temporary aws credentials can be passed directly to a redshift boto3 client, or in this case to redshift-connector. Below I've included a code snippit which shows how this can be done:

session = boto3.Session(
  # create the session with your aws credentials 
)
client = session.resource('sts')
creds = client.assume_role(
        RoleArn=RoleArn,
        RoleSessionName=RoleSessionName
)['Credentials'] 
# creds is the response payload from the assumeRole request. It has temporary AWS credentials which can now be
# passed to redshift-connector. See: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sts/client/assume_role.html

Regardless, this isn't very clean. Ideally, redshift-connector should be able to perform this role assumption internally using the steps I've provided above. As such, I will raise this feature request with the Redshift driver team so we can determine a path forward in improving the user experience for this scenario.

Fleid commented 5 days ago

Thanks a lot @Brooke-white - will relay the info on my side as well :)