sunchao commented on code in PR #5872:
URL: https://github.com/apache/datafusion-comet/pull/5872#discussion_r4173866124


##########
native/core/src/parquet/objectstore/s3.rs:
##########
@@ -1000,11 +1173,393 @@ impl CredentialProviderMetadata {
     }
 }
 
+/// The STS region the SDK profile provider takes, on its regional host, when 
no region is found.
+const STS_FALLBACK_REGION: &str = "us-east-1";
+
+/// The region whose STS endpoint is the global https://sts.amazonaws.com, 
signed for us-east-1,
+/// where the Java SDK sends a role profile's request when no region is found.
+const STS_GLOBAL_REGION: &str = "aws-global";
+
+/// Profile properties that make a profile resolve credentials other than its 
static keys.
+const CREDENTIAL_PROPERTIES: [&str; 10] = [
+    "role_arn",
+    "credential_source",
+    "web_identity_token_file",
+    "credential_process",
+    "login_session",
+    "sso_session",
+    "sso_account_id",
+    "sso_region",
+    "sso_role_name",
+    "sso_start_url",
+];
+
+/// A role a profile assumes from its `source_profile`.
+#[derive(Debug)]
+#[cfg_attr(test, derive(PartialEq))]
+struct ProfileRole {
+    role_arn: String,
+    external_id: Option<String>,
+    session_name: Option<String>,
+    region: Option<String>,
+}
+
+/// A role profile's chain: the profile whose credentials start it and the 
roles assumed from
+/// them, outermost first.
+#[derive(Debug)]
+#[cfg_attr(test, derive(PartialEq))]
+struct ProfileRoleChain {
+    base: String,
+    /// Whether the base is a web identity role, the only base that calls STS.
+    base_needs_region: bool,
+    roles: Vec<ProfileRole>,
+}
+
+fn has_only_static_keys(profile: &Profile) -> bool {
+    profile.get("aws_access_key_id").is_some()
+        && !CREDENTIAL_PROPERTIES
+            .iter()
+            .any(|property| profile.get(property).is_some())
+}
+
+/// Follows `role_arn` and `source_profile` from `selected` the way the SDK's 
profile provider
+/// does (aws-config's profile/credentials/repr.rs). That provider assumes 
every role with one
+/// STS region and offers no per-role endpoint, while Hadoop's Java SDK gives 
each role its own,
+/// so the roles are assumed here instead. A chain this does not mirror 
returns the reason, to
+/// stay on the SDK provider.
+fn resolve_role_chain(profiles: &ProfileSet, selected: &str) -> 
Result<ProfileRoleChain, String> {
+    let mut name = selected;
+    let mut visited = Vec::new();
+    let mut roles = Vec::new();
+    loop {
+        let profile = profiles
+            .get_profile(name)
+            .ok_or_else(|| format!("profile {name} is not defined"))?;
+        if visited.contains(&name) {
+            return Err(format!("profile {name} is in a source_profile cycle"));
+        }
+        visited.push(name);
+        // The SDK takes a source profile's static keys ahead of its other 
settings, which the
+        // base provider, reading the profile as its selected one, would not.
+        if visited.len() > 1
+            && profile.get("aws_access_key_id").is_some()
+            && !has_only_static_keys(profile)
+        {
+            return Err(format!(

Review Comment:
   [P2] Preserve Hadoop’s credential precedence for mixed source profiles. With 
the newly supported `ProfileAWSCredentialsProvider`, select an assume-role 
`[analytics]` profile whose `source_profile=source`, where `[source]` contains 
static keys and `credential_process`. Hadoop’s Java SDK gives 
`credential_process` precedence. This branch instead rejects the custom chain 
and delegates to the Rust SDK, which prioritizes a source profile’s static 
keys. Native therefore signs `AssumeRole` with a different identity and fails 
when only the process identity can assume the role. Could we resolve mixed 
source profiles using Java’s precedence instead of delegating the entire chain, 
and add a regression test asserting the signing key?
   
   Evidence: Reproduced with the verbatim current production profile-resolution 
block and locked aws-config 1.12.0, aws-runtime 1.9.2 and aws-sdk-sts 1.114.0. 
The fixture sets analytics.role_arn, analytics.source_profile=source and 
analytics.region=us-west-2. The source contains synthetic-source-key plus a 
credential_process returning synthetic-process-key. Native recorded an STS 
request signed by synthetic-source-key. Java SDK 2.29.52’s actual 
ProfileCredentialsUtils selected synthetic-process-key from the same fixture. 
An in-memory STS accepting only the process identity returned AccessDenied to 
native. Sources, fixture and outputs: 
/tmp/comet5872-c559-review/profile_probe.rs, JavaProfileOracle.java, 
java-mixed-process.credentials, profile_probe.log, java-oracle.log and 
restricted_profile_probe.log. No external STS requests were made.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to