This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch xuanwo/oss-pr4-network-credentials
in repository https://gitbox.apache.org/repos/asf/opendal-reqsign.git

commit f23c34d4439a65834621daa39edd0f272de1bdaf
Merge: 7378957 3dc1cf1
Author: Xuanwo <[email protected]>
AuthorDate: Thu Mar 19 02:55:21 2026 +0800

    Merge remote-tracking branch 'origin/main' into 
xuanwo/oss-pr4-network-credentials
    
    # Conflicts:
    #       services/aliyun-oss/README.md
    #       services/aliyun-oss/examples/oss_operations.rs
    #       services/aliyun-oss/src/lib.rs
    #       services/aliyun-oss/src/provide_credential/default.rs

 services/aliyun-oss/README.md                      |  64 ++-
 services/aliyun-oss/examples/oss_operations.rs     |  13 +-
 services/aliyun-oss/src/constants.rs               |   1 +
 services/aliyun-oss/src/lib.rs                     |  53 +-
 .../src/provide_credential/assume_role.rs          | 640 +++++++++++++++++++++
 .../aliyun-oss/src/provide_credential/default.rs   | 201 ++++++-
 services/aliyun-oss/src/provide_credential/mod.rs  |   3 +
 services/aliyun-oss/src/sign_request.rs            | 638 +++++++++++++++++++-
 8 files changed, 1544 insertions(+), 69 deletions(-)

diff --cc services/aliyun-oss/README.md
index ee10e66,27582ff..10aefc9
--- a/services/aliyun-oss/README.md
+++ b/services/aliyun-oss/README.md
@@@ -10,11 -10,10 +10,11 @@@ This crate provides signing support fo
  
  ```rust
  use reqsign_aliyun_oss::{
-     AssumeRoleWithOidcCredentialProvider, CredentialsUriCredentialProvider,
-     AssumeRoleWithOidcCredentialProvider, ConfigFileCredentialProvider,
-     CredentialsFileCredentialProvider, DefaultCredentialProvider,
-     EcsRamRoleCredentialProvider, EnvCredentialProvider,
-     OssProfileCredentialProvider, RequestSigner, StaticCredentialProvider,
+     AssumeRoleCredentialProvider, AssumeRoleWithOidcCredentialProvider,
 -    ConfigFileCredentialProvider, CredentialsFileCredentialProvider, 
DefaultCredentialProvider,
 -    EnvCredentialProvider, OssProfileCredentialProvider, RequestSigner,
 -    SigningVersion, StaticCredentialProvider,
++    ConfigFileCredentialProvider, CredentialsFileCredentialProvider,
++    CredentialsUriCredentialProvider, DefaultCredentialProvider,
++    EcsRamRoleCredentialProvider, EnvCredentialProvider, 
OssProfileCredentialProvider,
++    RequestSigner, SigningVersion, StaticCredentialProvider,
  };
  use reqsign_core::{Context, Result, Signer};
  use reqsign_file_read_tokio::TokioFileRead;
@@@ -63,8 -63,8 +66,9 @@@ async fn main() -> Result<()> 
  
  ## Features
  
- - **HMAC-SHA1 Signing**: Complete implementation of Aliyun's signing algorithm
- - **Multiple Credential Sources**: Environment variables, OSS profile files, 
Alibaba shared credential/config files, credentials URI, ECS RAM role metadata, 
and OIDC-based STS exchange
+ - **Multiple Credential Sources**: Environment variables, OSS profile files, 
Alibaba shared credential/config files, AssumeRole, and OIDC-based STS exchange
+ - **V1 and V4 Signing**: Supports both legacy OSS V1 signatures and Signature 
V4
++- **Runtime Credential Sources**: Credentials URI, ECS RAM role metadata, and 
OIDC-based STS exchange
  - **STS Support**: Temporary credentials via Security Token Service
  - **All OSS Operations**: Object, bucket, and multipart operations
  
@@@ -179,6 -158,6 +184,7 @@@ Reads from `~/.aliyun/config.json` by d
  Override the file path with `ALIBABA_CLOUD_CONFIG_FILE` and the selected 
profile with `ALIBABA_CLOUD_PROFILE`.
  
  Only direct static modes are loaded in this crate today: `AK` and `StsToken`.
++
  ### STS AssumeRole with OIDC
  
  For Kubernetes/ACK environments:
diff --cc services/aliyun-oss/examples/oss_operations.rs
index 2ff276d,09b5c6c..3b80205
--- a/services/aliyun-oss/examples/oss_operations.rs
+++ b/services/aliyun-oss/examples/oss_operations.rs
@@@ -16,10 -16,8 +16,10 @@@
  // under the License.
  
  use reqsign_aliyun_oss::{
-     AssumeRoleWithOidcCredentialProvider, ConfigFileCredentialProvider,
-     CredentialsFileCredentialProvider, CredentialsUriCredentialProvider, 
DefaultCredentialProvider,
-     EcsRamRoleCredentialProvider, EnvCredentialProvider, 
OssProfileCredentialProvider,
-     RequestSigner, StaticCredentialProvider,
+     AssumeRoleCredentialProvider, AssumeRoleWithOidcCredentialProvider, 
DefaultCredentialProvider,
 -    EnvCredentialProvider, RequestSigner, StaticCredentialProvider,
++    ConfigFileCredentialProvider, CredentialsFileCredentialProvider,
++    CredentialsUriCredentialProvider, EcsRamRoleCredentialProvider, 
EnvCredentialProvider,
++    OssProfileCredentialProvider, RequestSigner, StaticCredentialProvider,
  };
  use reqsign_core::Result;
  use reqsign_core::{Context, OsEnv, Signer};
@@@ -64,15 -62,10 +64,16 @@@ async fn main() -> Result<()> 
              StaticCredentialProvider::new("LTAI4GDemoAccessKeyId", 
"DemoAccessKeySecretForExample");
          Signer::new(ctx.clone(), loader, builder)
      } else {
-         // Build the default env -> oss_profile -> credentials_file -> 
config_file ->
-         // credentials_uri -> ecs_ram_role -> oidc chain.
 -        // Build the default assume_role -> env -> oidc chain explicitly via 
slot APIs.
++        // Build the default assume_role -> env -> oss_profile -> 
credentials_file ->
++        // config_file -> credentials_uri -> ecs_ram_role -> oidc chain.
          let loader = DefaultCredentialProvider::builder()
+             .assume_role(AssumeRoleCredentialProvider::new())
              .env(EnvCredentialProvider::new())
 +            .oss_profile(OssProfileCredentialProvider::new())
 +            .credentials_file(CredentialsFileCredentialProvider::new())
 +            .config_file(ConfigFileCredentialProvider::new())
 +            .credentials_uri(CredentialsUriCredentialProvider::new())
 +            .ecs_ram_role(EcsRamRoleCredentialProvider::new())
              .oidc(AssumeRoleWithOidcCredentialProvider::new())
              .build();
          Signer::new(ctx.clone(), loader, builder)
diff --cc services/aliyun-oss/src/constants.rs
index 82c8ccf,ca20192..590f11d
--- a/services/aliyun-oss/src/constants.rs
+++ b/services/aliyun-oss/src/constants.rs
@@@ -27,14 -27,9 +27,15 @@@ pub const OSS_ACCESS_KEY_SECRET: &str 
  pub const OSS_SESSION_TOKEN: &str = "OSS_SESSION_TOKEN";
  pub const OSS_PROFILE: &str = "OSS_PROFILE";
  pub const OSS_CREDENTIAL_PROFILES_FILE: &str = "OSS_CREDENTIAL_PROFILES_FILE";
 +pub const ALIBABA_CLOUD_CREDENTIALS_URI: &str = 
"ALIBABA_CLOUD_CREDENTIALS_URI";
 +pub const ALIBABA_CLOUD_ECS_METADATA: &str = "ALIBABA_CLOUD_ECS_METADATA";
 +pub const ALIBABA_CLOUD_ECS_METADATA_DISABLED: &str = 
"ALIBABA_CLOUD_ECS_METADATA_DISABLED";
 +pub const ALIBABA_CLOUD_ECS_METADATA_SERVICE_ENDPOINT: &str =
 +    "ALIBABA_CLOUD_ECS_METADATA_SERVICE_ENDPOINT";
 +pub const ALIBABA_CLOUD_IMDSV1_DISABLED: &str = 
"ALIBABA_CLOUD_IMDSV1_DISABLED";
  pub const ALIBABA_CLOUD_ROLE_ARN: &str = "ALIBABA_CLOUD_ROLE_ARN";
  pub const ALIBABA_CLOUD_ROLE_SESSION_NAME: &str = 
"ALIBABA_CLOUD_ROLE_SESSION_NAME";
+ pub const ALIBABA_CLOUD_EXTERNAL_ID: &str = "ALIBABA_CLOUD_EXTERNAL_ID";
  pub const ALIBABA_CLOUD_OIDC_PROVIDER_ARN: &str = 
"ALIBABA_CLOUD_OIDC_PROVIDER_ARN";
  pub const ALIBABA_CLOUD_OIDC_TOKEN_FILE: &str = 
"ALIBABA_CLOUD_OIDC_TOKEN_FILE";
  pub const ALIBABA_CLOUD_STS_ENDPOINT: &str = "ALIBABA_CLOUD_STS_ENDPOINT";
diff --cc services/aliyun-oss/src/lib.rs
index 82168ca,b10a938..39c4f9d
--- a/services/aliyun-oss/src/lib.rs
+++ b/services/aliyun-oss/src/lib.rs
@@@ -33,10 -33,10 +33,11 @@@
  //!
  //! ```no_run
  //! use reqsign_aliyun_oss::{
- //!     AssumeRoleWithOidcCredentialProvider, 
CredentialsUriCredentialProvider,
+ //!     AssumeRoleCredentialProvider, AssumeRoleWithOidcCredentialProvider,
 -//!     ConfigFileCredentialProvider, CredentialsFileCredentialProvider, 
DefaultCredentialProvider,
 -//!     EnvCredentialProvider, OssProfileCredentialProvider, RequestSigner,
 -//!     SigningVersion, StaticCredentialProvider,
 +//!     ConfigFileCredentialProvider, CredentialsFileCredentialProvider,
- //!     DefaultCredentialProvider, EcsRamRoleCredentialProvider, 
EnvCredentialProvider,
- //!     OssProfileCredentialProvider, RequestSigner, StaticCredentialProvider,
++//!     CredentialsUriCredentialProvider, DefaultCredentialProvider,
++//!     EcsRamRoleCredentialProvider, EnvCredentialProvider, 
OssProfileCredentialProvider,
++//!     RequestSigner, SigningVersion, StaticCredentialProvider,
  //! };
  //! use reqsign_core::{Context, Signer, Result};
  //! use reqsign_file_read_tokio::TokioFileRead;
@@@ -49,10 -49,10 +50,11 @@@
  //!         .with_file_read(TokioFileRead::default())
  //!         .with_http_send(ReqwestHttpSend::default());
  //!
- //!     // Create credential loader with the default env -> OSS profile ->
- //!     // shared credentials file -> config file -> credentials URI ->
- //!     // ECS RAM role -> oidc chain.
+ //!     // Create credential loader with the default assume_role -> env ->
 -//!     // OSS profile -> shared credentials file -> config file -> oidc 
chain.
++//!     // OSS profile -> shared credentials file -> config file ->
++//!     // credentials URI -> ECS RAM role -> oidc chain.
  //!     let loader = DefaultCredentialProvider::builder()
+ //!         .assume_role(AssumeRoleCredentialProvider::new())
  //!         .env(EnvCredentialProvider::new())
  //!         .oss_profile(OssProfileCredentialProvider::new())
  //!         .credentials_file(CredentialsFileCredentialProvider::new())
@@@ -106,13 -106,8 +110,17 @@@
  //! The crate can load credentials from the OSS profile file
  //! (typically `~/.oss/credentials`).
  //!
 +//! ### Credentials URI
 +//!
 +//! The crate can load temporary credentials from
 +//! `ALIBABA_CLOUD_CREDENTIALS_URI`.
 +//!
 +//! ### ECS RAM Role
 +//!
++//! The crate can load temporary credentials from the ECS metadata service.
++//!
+ //! ### Alibaba Shared Credential and Config Files
+ //!
  //! The crate can also load static credentials from Alibaba shared SDK files
  //! (`~/.alibabacloud/credentials.ini`, `~/.aliyun/credentials.ini`) and the
  //! Alibaba CLI config file (`~/.aliyun/config.json`).
@@@ -168,13 -163,18 +176,20 @@@
  //! let loader = DefaultCredentialProvider::builder()
  //!     .no_env()
  //!     .no_oss_profile()
 +//!     .no_credentials_uri()
 +//!     .no_ecs_ram_role()
  //!     .no_credentials_file()
  //!     .no_config_file()
- //!     .oidc(
- //!         
AssumeRoleWithOidcCredentialProvider::new().with_role_session_name("my-session"),
+ //!     .assume_role(
+ //!         AssumeRoleCredentialProvider::new()
+ //!             .with_base_provider(StaticCredentialProvider::new(
+ //!                 "your-access-key-id",
+ //!                 "your-access-key-secret",
+ //!             ))
+ //!             .with_role_arn("acs:ram::123456789012:role/example")
+ //!             .with_role_session_name("my-session"),
  //!     )
+ //!     .no_oidc()
  //!     .build();
  //! ```
  //!
diff --cc services/aliyun-oss/src/provide_credential/default.rs
index 871e1a1,9e8b1c0..cacc23e
--- a/services/aliyun-oss/src/provide_credential/default.rs
+++ b/services/aliyun-oss/src/provide_credential/default.rs
@@@ -17,9 -17,9 +17,10 @@@
  
  use crate::Credential;
  use crate::provide_credential::{
-     AssumeRoleWithOidcCredentialProvider, ConfigFileCredentialProvider,
-     CredentialsFileCredentialProvider, CredentialsUriCredentialProvider,
-     EcsRamRoleCredentialProvider, EnvCredentialProvider, 
OssProfileCredentialProvider,
+     AssumeRoleCredentialProvider, AssumeRoleWithOidcCredentialProvider,
 -    ConfigFileCredentialProvider, CredentialsFileCredentialProvider, 
EnvCredentialProvider,
++    ConfigFileCredentialProvider, CredentialsFileCredentialProvider,
++    CredentialsUriCredentialProvider, EcsRamRoleCredentialProvider, 
EnvCredentialProvider,
+     OssProfileCredentialProvider,
  };
  use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, 
Result};
  
@@@ -27,13 -27,12 +28,14 @@@
  ///
  /// Resolution order:
  ///
- /// 1. Environment variables
- /// 2. OSS profile file
- /// 3. Alibaba shared credentials file
- /// 4. Alibaba CLI config file
- /// 5. Credentials URI
- /// 6. ECS RAM role metadata
- /// 7. Assume Role with OIDC
+ /// 1. AssumeRole via base AK credentials
+ /// 2. Environment variables
+ /// 3. OSS profile file
+ /// 4. Alibaba shared credentials file
+ /// 5. Alibaba CLI config file
 -/// 6. Assume Role with OIDC
++/// 6. Credentials URI
++/// 7. ECS RAM role metadata
++/// 8. Assume Role with OIDC
  #[derive(Debug)]
  pub struct DefaultCredentialProvider {
      chain: ProvideCredentialChain<Credential>,
@@@ -88,10 -87,9 +90,11 @@@ impl DefaultCredentialProvider 
  /// Use `slot(provider)` to override a default provider or `no_slot()` to
  /// remove it from the chain before calling `build()`.
  pub struct DefaultCredentialProviderBuilder {
+     assume_role: Option<AssumeRoleCredentialProvider>,
      env: Option<EnvCredentialProvider>,
      oss_profile: Option<OssProfileCredentialProvider>,
 +    credentials_uri: Option<CredentialsUriCredentialProvider>,
 +    ecs_ram_role: Option<EcsRamRoleCredentialProvider>,
      credentials_file: Option<CredentialsFileCredentialProvider>,
      config_file: Option<ConfigFileCredentialProvider>,
      oidc: Option<AssumeRoleWithOidcCredentialProvider>,
@@@ -100,10 -98,9 +103,11 @@@
  impl Default for DefaultCredentialProviderBuilder {
      fn default() -> Self {
          Self {
+             assume_role: Some(AssumeRoleCredentialProvider::new()),
              env: Some(EnvCredentialProvider::new()),
              oss_profile: Some(OssProfileCredentialProvider::new()),
 +            credentials_uri: Some(CredentialsUriCredentialProvider::new()),
 +            ecs_ram_role: Some(EcsRamRoleCredentialProvider::new()),
              credentials_file: Some(CredentialsFileCredentialProvider::new()),
              config_file: Some(ConfigFileCredentialProvider::new()),
              oidc: Some(AssumeRoleWithOidcCredentialProvider::new()),
@@@ -573,10 -566,9 +621,11 @@@ access_key_secret=shared_secret_ke
              });
  
          let credential = DefaultCredentialProvider::builder()
+             .no_assume_role()
              .no_env()
              .no_oss_profile()
 +            .no_credentials_uri()
 +            .no_ecs_ram_role()
              .no_oidc()
              .build()
              .provide_credential(&ctx)
@@@ -1005,10 -773,9 +1058,11 @@@
              });
  
          let credential = DefaultCredentialProvider::builder()
+             .no_assume_role()
              .no_env()
              .no_oss_profile()
 +            .no_credentials_uri()
 +            .no_ecs_ram_role()
              .oidc(AssumeRoleWithOidcCredentialProvider::new())
              .build()
              .provide_credential(&ctx)
@@@ -1019,10 -786,9 +1073,11 @@@
          assert_eq!(1, http_send.calls());
  
          let credential = DefaultCredentialProvider::builder()
+             .no_assume_role()
              .no_env()
              .no_oss_profile()
 +            .no_credentials_uri()
 +            .no_ecs_ram_role()
              .no_oidc()
              .build()
              .provide_credential(&ctx)

Reply via email to