Skip to content

Commit b769507

Browse files
authored
fix(query): enable role-based S3 credential chain (#19188)
fix: enable role-based S3 credential chain
1 parent 10c5ba6 commit b769507

File tree

3 files changed

+17
-16
lines changed

3 files changed

+17
-16
lines changed

src/common/storage/src/operator.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,11 @@ fn init_s3_operator(cfg: &StorageS3Config) -> Result<impl Builder> {
416416
builder = builder.default_storage_class(cfg.storage_class.to_string().as_ref())
417417
}
418418

419-
// If allow_credential_chain is not set, default to false for security.
420-
let allow_credential_chain = cfg.allow_credential_chain.unwrap_or(false);
419+
// When a role is configured we must allow the credential chain so AWS can assume it,
420+
// otherwise we should disable the credential chain for security.
421+
let allow_credential_chain = cfg
422+
.allow_credential_chain
423+
.unwrap_or(!cfg.role_arn.is_empty());
421424

422425
// Disallowing the credential chain forces unsigned or fully explicit access.
423426
if !allow_credential_chain {

src/common/storage/src/stage.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,13 @@ impl StageFileInfo {
8888
pub fn init_stage_operator(stage_info: &StageInfo) -> Result<Operator> {
8989
if stage_info.stage_type == StageType::External {
9090
// External S3 stages disallow the ambient credential chain by default.
91-
// `role_arn` opts into using the credential chain as the source credential.
91+
// The S3 operator builder will re-enable it automatically when a role_arn is present.
92+
// This hook only needs to force-enable the chain for cases like system history tables.
9293
let storage = match stage_info.stage_params.storage.clone() {
9394
StorageParams::S3(mut cfg) => {
94-
let allow_credential_chain =
95-
stage_info.allow_credential_chain || !cfg.role_arn.is_empty();
96-
cfg.allow_credential_chain = Some(allow_credential_chain);
95+
if stage_info.allow_credential_chain {
96+
cfg.allow_credential_chain = Some(true);
97+
}
9798
StorageParams::S3(cfg)
9899
}
99100
v => v,

src/query/sql/src/planner/binder/location.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,13 @@ fn parse_s3_params(l: &mut UriLocation, root: String) -> Result<StorageParams> {
172172
}
173173
.to_string();
174174

175-
// If role_arn is empty, we should not allow credential chain.
176-
let mut allow_credential_chain = Some(!role_arn.is_empty());
177-
178-
// If we are in history table scope, we allow credential loader to be enabled
179-
let in_history_table_scope = ThreadTracker::capture_log_settings()
180-
.is_some_and(|settings| settings.level == LevelFilter::Off);
181-
if in_history_table_scope {
182-
info!("Allow credential chain for history tables");
183-
allow_credential_chain = Some(true);
184-
}
175+
// Enable credential chain explicitly only in history-table scope.
176+
let allow_credential_chain = ThreadTracker::capture_log_settings()
177+
.is_some_and(|settings| settings.level == LevelFilter::Off)
178+
.then(|| {
179+
info!("Allow credential chain for history tables");
180+
true
181+
});
185182

186183
let sp = StorageParams::S3(StorageS3Config {
187184
endpoint_url: secure_omission(endpoint),

0 commit comments

Comments
 (0)