Skip to content

Commit ed9f6ba

Browse files
authored
Priorize ECS/EKS credentials over EC2 when available (#441)
- Move container credentials logic out of the IMDSv1 function - Priorize it over IMDSv2 like before #378
1 parent d88c5f4 commit ed9f6ba

File tree

2 files changed

+41
-30
lines changed

2 files changed

+41
-30
lines changed

aws-creds/src/credentials.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ impl Credentials {
296296
#[cfg(feature = "http-credentials")]
297297
let credentials = credentials
298298
.or_else(|_| Credentials::from_sts_env("aws-creds"))
299+
.or_else(|_| Credentials::from_container_credentials_provider())
299300
.or_else(|_| Credentials::from_instance_metadata_v2(false))
300301
.or_else(|_| Credentials::from_instance_metadata(false));
301302

@@ -326,38 +327,46 @@ impl Credentials {
326327
Credentials::from_env_specific(None, None, None, None)
327328
}
328329

330+
#[cfg(feature = "http-credentials")]
331+
pub fn from_container_credentials_provider() -> Result<Credentials, CredentialsError> {
332+
let Ok(credentials_path) = env::var("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") else {
333+
return Err(CredentialsError::NotContainer);
334+
};
335+
336+
let resp: CredentialsFromInstanceMetadata = apply_timeout(attohttpc::get(format!(
337+
"http://169.254.170.2{}",
338+
credentials_path
339+
)))
340+
.send()?
341+
.json()?;
342+
343+
Ok(Credentials {
344+
access_key: Some(resp.access_key_id),
345+
secret_key: Some(resp.secret_access_key),
346+
security_token: Some(resp.token),
347+
expiration: Some(resp.expiration),
348+
session_token: None,
349+
})
350+
}
351+
329352
#[cfg(feature = "http-credentials")]
330353
pub fn from_instance_metadata(not_ec2: bool) -> Result<Credentials, CredentialsError> {
331-
let resp: CredentialsFromInstanceMetadata =
332-
match env::var("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") {
333-
Ok(credentials_path) => {
334-
// We are on ECS
335-
apply_timeout(attohttpc::get(format!(
336-
"http://169.254.170.2{}",
337-
credentials_path
338-
)))
339-
.send()?
340-
.json()?
341-
}
342-
Err(_) => {
343-
if !not_ec2 && !is_ec2() {
344-
return Err(CredentialsError::NotEc2);
345-
}
346-
347-
let role = apply_timeout(attohttpc::get(
348-
"http://169.254.169.254/latest/meta-data/iam/security-credentials",
349-
))
350-
.send()?
351-
.text()?;
352-
353-
apply_timeout(attohttpc::get(format!(
354-
"http://169.254.169.254/latest/meta-data/iam/security-credentials/{}",
355-
role
356-
)))
357-
.send()?
358-
.json()?
359-
}
360-
};
354+
if !not_ec2 && !is_ec2() {
355+
return Err(CredentialsError::NotEc2);
356+
}
357+
358+
let role = apply_timeout(attohttpc::get(
359+
"http://169.254.169.254/latest/meta-data/iam/security-credentials",
360+
))
361+
.send()?
362+
.text()?;
363+
364+
let resp: CredentialsFromInstanceMetadata = apply_timeout(attohttpc::get(format!(
365+
"http://169.254.169.254/latest/meta-data/iam/security-credentials/{}",
366+
role
367+
)))
368+
.send()?
369+
.json()?;
361370

362371
Ok(Credentials {
363372
access_key: Some(resp.access_key_id),

aws-creds/src/error.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use thiserror::Error;
44
pub enum CredentialsError {
55
#[error("Not an AWS instance")]
66
NotEc2,
7+
#[error("Not a container")]
8+
NotContainer,
79
#[error("Config not found")]
810
ConfigNotFound,
911
#[error("Missing aws_access_key_id section in config")]

0 commit comments

Comments
 (0)