Skip to content

Commit e672e7b

Browse files
committed
fix(agents): remove rusoto-based AWS region validation for signer config
PR #8669 removed rusoto's `FromStr` validation for S3 checkpoint-syncer regions but missed the same validation on agent signer regions (`validator.region`, `chains.<name>.signer.region`), which still rejected regions like `eu-central-2`. Store `SignerConf::Aws.region` as a plain `String` and resolve it to a `rusoto_core::Region` at KMS client construction time: use the enum variant when rusoto recognizes the name, otherwise fall back to `Region::Custom` with a synthesized commercial KMS endpoint.
1 parent 60dbe23 commit e672e7b

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

rust/main/hyperlane-base/src/settings/parser/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,9 @@ fn parse_signer(signer: ValueParser) -> ConfigResult<SignerConf> {
456456
let region = signer
457457
.chain(&mut err)
458458
.get_key("region")
459-
.parse_from_str("Expected AWS region")
460-
.unwrap_or_default();
459+
.parse_string()
460+
.unwrap_or_default()
461+
.to_owned();
461462
err.into_result(SignerConf::Aws { id, region })
462463
}};
463464
(cosmosKey) => {{

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ethers::utils::hex::ToHex;
77
use eyre::{bail, Context, Report};
88
use rusoto_core::Region;
99
use rusoto_kms::KmsClient;
10+
use std::str::FromStr;
1011
use tracing::instrument;
1112

1213
use hyperlane_core::{AccountAddressType, H256};
@@ -16,6 +17,16 @@ use crate::types::utils;
1617

1718
const AWS_SIGNER_TIMEOUT: Duration = Duration::from_secs(30);
1819

20+
/// Resolve an AWS region string into a `rusoto_core::Region` without relying on
21+
/// rusoto's `FromStr` allowlist, which rejects regions added after rusoto was
22+
/// last updated (e.g. `eu-central-2`).
23+
fn resolve_kms_region(region: &str) -> Region {
24+
Region::from_str(region).unwrap_or_else(|_| Region::Custom {
25+
name: region.to_owned(),
26+
endpoint: format!("https://kms.{region}.amazonaws.com"),
27+
})
28+
}
29+
1930
/// Signer types
2031
#[derive(Default, Debug, Clone)]
2132
pub enum SignerConf {
@@ -30,7 +41,7 @@ pub enum SignerConf {
3041
/// The UUID identifying the AWS KMS Key
3142
id: String,
3243
/// The AWS region
33-
region: Region,
44+
region: String,
3445
},
3546
/// Cosmos Specific key
3647
CosmosKey {
@@ -100,7 +111,7 @@ impl BuildableWithSignerConf for hyperlane_ethereum::Signers {
100111
.map_err(|err| eyre::eyre!(err.to_string()))?;
101112
let client = KmsClient::new_with_client(
102113
rusoto_core::Client::new_with(AwsChainCredentialsProvider::new(), http_client),
103-
region.clone(),
114+
resolve_kms_region(region),
104115
);
105116
let signer = AwsSigner::new(client, id, 0, Some(AWS_SIGNER_TIMEOUT)).await?;
106117
hyperlane_ethereum::Signers::Aws(signer)
@@ -142,7 +153,7 @@ impl BuildableWithSignerConf for hyperlane_tron::TronSigner {
142153
.map_err(|err| eyre::eyre!(err.to_string()))?;
143154
let client = KmsClient::new_with_client(
144155
rusoto_core::Client::new_with(AwsChainCredentialsProvider::new(), http_client),
145-
region.clone(),
156+
resolve_kms_region(region),
146157
);
147158
let signer = AwsSigner::new(client, id, 0, Some(AWS_SIGNER_TIMEOUT)).await?;
148159
Ok(hyperlane_tron::TronSigner::Aws(signer))
@@ -323,9 +334,28 @@ impl ChainSigner for hyperlane_aleo::AleoSigner {
323334
mod tests {
324335
use ethers::{signers::LocalWallet, utils::hex};
325336
use hyperlane_core::{AccountAddressType, Encode, H256};
337+
use rusoto_core::Region;
326338

339+
use super::resolve_kms_region;
327340
use crate::settings::{ChainSigner, SignerConf};
328341

342+
#[test]
343+
fn resolve_kms_region_known_region_uses_enum_variant() {
344+
assert_eq!(resolve_kms_region("us-east-1"), Region::UsEast1);
345+
}
346+
347+
#[test]
348+
fn resolve_kms_region_unknown_region_uses_custom() {
349+
let region = resolve_kms_region("eu-central-2");
350+
match region {
351+
Region::Custom { name, endpoint } => {
352+
assert_eq!(name, "eu-central-2");
353+
assert_eq!(endpoint, "https://kms.eu-central-2.amazonaws.com");
354+
}
355+
other => panic!("expected Region::Custom, got {other:?}"),
356+
}
357+
}
358+
329359
#[test]
330360
fn address_h256_ethereum() {
331361
const PRIVATE_KEY: &str =

0 commit comments

Comments
 (0)