Skip to content

Commit f724f79

Browse files
Sungum Soganiluis-garza-dev
authored andcommitted
feat: Added support for Identity Enhanced Credentials authentication
1 parent 3e1c312 commit f724f79

8 files changed

Lines changed: 934 additions & 21 deletions

File tree

redshift_connector/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,12 @@ def connect(
303303
The access token to be used with IdC basic credentials provider plugin. Default value is None.
304304
token_type: Optional[str]
305305
The token type to be used for authentication using IdP token auth plugin. Default value is None.
306+
access_key_id : Optional[str]
307+
The access key for the user configured for IAM database authentication. Can also be used with IdpTokenAuthPlugin for identity-enhanced credentials flow.
308+
secret_access_key : Optional[str]
309+
The secret access key for the IAM role or IAM user configured for IAM database authentication. Can also be used with IdpTokenAuthPlugin for identity-enhanced credentials flow.
310+
session_token : Optional[str]
311+
The session token for temporary AWS credentials. Required when using temporary credentials with IAM authentication or IdpTokenAuthPlugin identity-enhanced credentials flow.
306312
Returns
307313
-------
308314
A Connection object associated with the specified Amazon Redshift cluster: :class:`Connection`
@@ -458,6 +464,9 @@ def connect(
458464
identity_namespace=info.identity_namespace,
459465
token_type=info.token_type,
460466
idc_client_display_name=info.idc_client_display_name,
467+
access_key_id=info.access_key_id,
468+
secret_access_key=info.secret_access_key,
469+
session_token=info.session_token,
461470
)
462471

463472

redshift_connector/core.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,9 @@ def __init__(
432432
identity_namespace: typing.Optional[str] = None,
433433
token_type: typing.Optional[str] = None,
434434
idc_client_display_name: typing.Optional[str] = None,
435+
access_key_id: typing.Optional[str] = None,
436+
secret_access_key: typing.Optional[str] = None,
437+
session_token: typing.Optional[str] = None,
435438
):
436439
"""
437440
Creates a :class:`Connection` to an Amazon Redshift cluster. For more information on establishing a connection to an Amazon Redshift cluster using `federated API access <https://aws.amazon.com/blogs/big-data/federated-api-access-to-amazon-redshift-using-an-amazon-redshift-connector-for-python/>`_ see our examples page.
@@ -486,6 +489,12 @@ def __init__(
486489
The token type to be used for authentication using IdP Token auth plugin
487490
idc_client_display_name: Optional[str]
488491
The client display name to be used for user consent in IdC browser auth plugin.
492+
access_key_id: Optional[str]
493+
The AWS access key ID for identity-enhanced credentials flow with IdpTokenAuthPlugin.
494+
secret_access_key: Optional[str]
495+
The AWS secret access key for identity-enhanced credentials flow with IdpTokenAuthPlugin.
496+
session_token: Optional[str]
497+
The AWS session token for identity-enhanced credentials flow with IdpTokenAuthPlugin.
489498
"""
490499
self.merge_socket_read = True
491500

@@ -570,7 +579,10 @@ def get_calling_module() -> str:
570579
"BrowserIdcAuthPlugin",
571580
):
572581
redshift_native_auth = True
573-
self.set_idc_plugins_params(init_params, credentials_provider, identity_namespace, token_type)
582+
self.set_idc_plugins_params(init_params, credentials_provider,
583+
identity_namespace, token_type, idc_client_display_name,
584+
access_key_id, secret_access_key, session_token
585+
)
574586

575587
if redshift_native_auth and provider_name:
576588
init_params["provider_name"] = provider_name
@@ -2520,6 +2532,9 @@ def set_idc_plugins_params(
25202532
identity_namespace: typing.Optional[str] = None,
25212533
token_type: typing.Optional[str] = None,
25222534
idc_client_display_name: typing.Optional[str] = None,
2535+
access_key_id: typing.Optional[str] = None,
2536+
secret_access_key: typing.Optional[str] = None,
2537+
session_token: typing.Optional[str] = None,
25232538
) -> None:
25242539
plugin_name = typing.cast(str, credentials_provider).split(".")[-1]
25252540
init_params["idp_type"] = "AwsIdc"
@@ -2529,6 +2544,9 @@ def set_idc_plugins_params(
25292544

25302545
if plugin_name == "BrowserIdcAuthPlugin":
25312546
init_params["token_type"] = "ACCESS_TOKEN"
2547+
elif plugin_name == "IdpTokenAuthPlugin" and access_key_id and secret_access_key and session_token:
2548+
# Check if using identity-enhanced credentials flow with IdPTokenAuthPlugin
2549+
init_params["token_type"] = "SUBJECT_TOKEN"
25322550
elif token_type:
25332551
init_params["token_type"] = token_type
25342552

redshift_connector/iam_helper.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ def set_iam_properties(info: RedshiftProperty) -> RedshiftProperty:
137137
if not info.region:
138138
info.set_region_from_host()
139139

140+
# Extract cluster_identifier from host for provisioned clusters if not already set
141+
# This is needed for IDC plugins (like IdpTokenAuthPlugin) which don't use iam=True
142+
if info.iam is not True and info.cluster_identifier is None and info.is_provisioned_host:
143+
info.set_cluster_identifier_from_host()
144+
140145
if info.iam is True:
141146
if info.region is None:
142147
_logger.debug("Setting region via DNS lookup as region was not provided in connection parameters")

0 commit comments

Comments
 (0)