Skip to content

Commit fa5c311

Browse files
authored
feat: Allow fetching aws signer keys with container provider (#7695)
1 parent 2f70f7f commit fa5c311

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

rust/main/hyperlane-base/src/settings/aws_credentials.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@
33

44
use async_trait::async_trait;
55
use rusoto_core::credential::{
6-
AutoRefreshingProvider, AwsCredentials, CredentialsError, EnvironmentProvider,
7-
ProvideAwsCredentials,
6+
AutoRefreshingProvider, AwsCredentials, ContainerProvider, CredentialsError,
7+
EnvironmentProvider, ProvideAwsCredentials,
88
};
99
use rusoto_sts::WebIdentityProvider;
1010

1111
/// Provides AWS credentials from multiple possible sources using a priority order.
12-
/// The following sources are checked in order for credentials when calling credentials. More sources may be supported in future if a need be.
12+
/// The following sources are checked in order for credentials when calling credentials:
1313
/// 1) Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
14-
/// 2) `WebIdentityProvider`: by default, configured from environment variables `AWS_WEB_IDENTITY_TOKEN_FILE`,
14+
/// 2) `ContainerProvider`: ECS container credentials from the task metadata endpoint.
15+
/// This is used when running in ECS/Fargate with an IAM task role.
16+
/// 3) `WebIdentityProvider`: by default, configured from environment variables `AWS_WEB_IDENTITY_TOKEN_FILE`,
1517
/// `AWS_ROLE_ARN` and `AWS_ROLE_SESSION_NAME`. Uses OpenID Connect bearer token to retrieve AWS IAM credentials
1618
/// from [AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html).
1719
/// The primary use case is running Hyperlane agents in AWS Kubernetes cluster (EKS) configured
1820
/// with [IAM Roles for Service Accounts (IRSA)](https://aws.amazon.com/blogs/containers/diving-into-iam-roles-for-service-accounts/).
1921
/// The IRSA approach follows security best practices and allows for key rotation.
2022
pub(crate) struct AwsChainCredentialsProvider {
2123
environment_provider: EnvironmentProvider,
24+
container_provider: AutoRefreshingProvider<ContainerProvider>,
2225
web_identity_provider: AutoRefreshingProvider<WebIdentityProvider>,
2326
}
2427

@@ -30,8 +33,11 @@ impl AwsChainCredentialsProvider {
3033
let auto_refreshing_provider =
3134
AutoRefreshingProvider::new(WebIdentityProvider::from_k8s_env())
3235
.expect("Always returns Ok(...)");
36+
let container_provider =
37+
AutoRefreshingProvider::new(ContainerProvider::new()).expect("Always returns Ok(...)");
3338
AwsChainCredentialsProvider {
3439
environment_provider: EnvironmentProvider::default(),
40+
container_provider,
3541
web_identity_provider: auto_refreshing_provider,
3642
}
3743
}
@@ -40,11 +46,17 @@ impl AwsChainCredentialsProvider {
4046
#[async_trait]
4147
impl ProvideAwsCredentials for AwsChainCredentialsProvider {
4248
async fn credentials(&self) -> Result<AwsCredentials, CredentialsError> {
49+
// Try environment variables first
4350
if let Ok(creds) = self.environment_provider.credentials().await {
44-
Ok(creds)
45-
} else {
46-
// Propagate errors from the 'WebIdentityProvider'.
47-
self.web_identity_provider.credentials().await
51+
return Ok(creds);
4852
}
53+
54+
// Try ECS container credentials (for Fargate/ECS with task role)
55+
if let Ok(creds) = self.container_provider.credentials().await {
56+
return Ok(creds);
57+
}
58+
59+
// Fall back to web identity (for Kubernetes IRSA)
60+
self.web_identity_provider.credentials().await
4961
}
5062
}

0 commit comments

Comments
 (0)