Feature Request / Improvement
Currently, RESTSigV4AuthSession calls the restCredentialsProvider function in AwsProperties to retrieve the credentials provider to sign the sigv4 request.
The restCredentialsProvider function currently follows the following decision chain:
- If
accessKeyId, secretAccessKey, and optionally sessionToken are set -> return a StaticCredentialsProvider
- If
clientCredentialsProvider is set, build the class using DynClasses and pass the property map clientCredentialsProviderProperties into the create function of the class
- Otherwise return the default credential chain using
DefaultCredentialsProvider.
However, this decision chain does not consider the credentials if client.factory=org.apache.iceberg.aws.AssumeRoleAwsClientFactory. The factory will define a role to assume that ISN'T used on REST catalog requests but IS used for S3FileIO, Glue Catalog, KMS, and DynamoDB operations causing divergent permissions for REST catalog operations.
Workarounds attempted:
AwsProperties allows the definition of alternative credential providers under client.credentials-provider. When this property is set, restCredentialsProvider will return the custom provider instead of the default chain.
However, this property is not compatible with software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider since this property requires the credentials provider to have a create() or create(Map) function, while the assume role provider uses the builder pattern.
Potential Design:
Fastest path would be to update the credentialsProvider(String accessKeyId, String secretAccessKey, String sessionToken) function of AwsProperties to create and return a StsAssumeRoleCredentialsProvider if this.clientAssumeRoleArn is set. The AwsProperties class would be duplicating the createCredentialsProvider function of AssumeRoleAwsClientFactory. This could go between step 2 and 3 of the decision chain of restCredentialsProvider (before returning default credentials chain, check for clientAssumeRoleArn first and if it is set return the assume role credentials provider).
A more complete path would be to define another interface (possibly named CanCreateAwsCredentialsProvider?) that has a public function AwsCredentialsProvider createCredentialsProvider(). AssumeRoleAwsClientFactory can implement this class (and possibly other client factories such as LakeFormationAwsClientFactory). When CLIENT_FACTORY is set to a class that inherits this interface, instantiate the client factory and call the function between step 2 and 3 of the decision chain of restCredentialsProvider.
Third possible design: extract the four functions (sts, genSessionName, createCredentialsProvider, createAssumeRoleRequest) from AssumeRoleAwsClientFactory into a separate public utility class. Embed the utility class into both AwsProperties and AssumeRoleAwsClientFactory. Add a set of additional rest. properties for assume role as well.
Query engine
Spark
Willingness to contribute
Feature Request / Improvement
Currently,
RESTSigV4AuthSessioncalls therestCredentialsProviderfunction inAwsPropertiesto retrieve the credentials provider to sign the sigv4 request.The
restCredentialsProviderfunction currently follows the following decision chain:accessKeyId,secretAccessKey, and optionallysessionTokenare set -> return aStaticCredentialsProviderclientCredentialsProvideris set, build the class usingDynClassesand pass the property mapclientCredentialsProviderPropertiesinto the create function of the classDefaultCredentialsProvider.However, this decision chain does not consider the credentials if
client.factory=org.apache.iceberg.aws.AssumeRoleAwsClientFactory. The factory will define a role to assume that ISN'T used on REST catalog requests but IS used for S3FileIO, Glue Catalog, KMS, and DynamoDB operations causing divergent permissions for REST catalog operations.Workarounds attempted:
AwsProperties allows the definition of alternative credential providers under
client.credentials-provider. When this property is set,restCredentialsProviderwill return the custom provider instead of the default chain.However, this property is not compatible with
software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvidersince this property requires the credentials provider to have acreate()orcreate(Map)function, while the assume role provider uses the builder pattern.Potential Design:
Fastest path would be to update the
credentialsProvider(String accessKeyId, String secretAccessKey, String sessionToken)function ofAwsPropertiesto create and return aStsAssumeRoleCredentialsProviderifthis.clientAssumeRoleArnis set. TheAwsPropertiesclass would be duplicating thecreateCredentialsProviderfunction ofAssumeRoleAwsClientFactory. This could go between step 2 and 3 of the decision chain ofrestCredentialsProvider(before returning default credentials chain, check forclientAssumeRoleArnfirst and if it is set return the assume role credentials provider).A more complete path would be to define another interface (possibly named
CanCreateAwsCredentialsProvider?) that has a public functionAwsCredentialsProvider createCredentialsProvider().AssumeRoleAwsClientFactorycan implement this class (and possibly other client factories such asLakeFormationAwsClientFactory). WhenCLIENT_FACTORYis set to a class that inherits this interface, instantiate the client factory and call the function between step 2 and 3 of the decision chain ofrestCredentialsProvider.Third possible design: extract the four functions (sts, genSessionName, createCredentialsProvider, createAssumeRoleRequest) from AssumeRoleAwsClientFactory into a separate public utility class. Embed the utility class into both AwsProperties and AssumeRoleAwsClientFactory. Add a set of additional
rest.properties for assume role as well.Query engine
Spark
Willingness to contribute