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

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


The following commit(s) were added to refs/heads/main by this push:
     new 635f0bc  refactor: adopt MaybeSend futures and remove async_trait 
(#702)
635f0bc is described below

commit 635f0bceb6aafde7678c82ecc51041d02add636e
Author: Xuanwo <[email protected]>
AuthorDate: Tue Mar 3 16:52:41 2026 +0800

    refactor: adopt MaybeSend futures and remove async_trait (#702)
    
    This PR replaces `async_trait`-based async trait methods with an
    OpenDAL-style `MaybeSend` future model across reqsign. It keeps the
    single-trait architecture while making wasm/non-wasm send bounds
    explicit through shared future aliases.
    
    To preserve object safety and existing ergonomics, this change
    introduces `*Dyn` adapters (`HttpSendDyn`, `FileReadDyn`,
    `CommandExecuteDyn`, `ProvideCredentialDyn`, `SignRequestDyn`) and keeps
    public builder APIs (`Context`, `Signer`, provider chains) working with
    trait objects.
    
    ## Context
    - Aligns reqsign with the same `MaybeSend` direction used by OpenDAL.
    - Removes all `async-trait` usage and corresponding crate dependencies
    across the workspace.
---
 .github/workflows/ci.yml                           |  14 +++
 Cargo.toml                                         |   2 +-
 context/command-execute-tokio/Cargo.toml           |   5 +-
 context/command-execute-tokio/src/lib.rs           |  17 +++-
 context/file-read-tokio/Cargo.toml                 |   1 -
 context/file-read-tokio/src/lib.rs                 |   4 -
 context/http-send-reqwest/Cargo.toml               |   1 -
 context/http-send-reqwest/src/lib.rs               |   4 -
 core/Cargo.toml                                    |   2 +-
 core/src/api.rs                                    | 110 ++++++++++++++++++---
 core/src/context.rs                                | 105 ++++++++++++++++----
 core/src/futures_util.rs                           |  42 ++++++++
 core/src/lib.rs                                    |  19 ++--
 core/src/signer.rs                                 |  17 +++-
 services/aliyun-oss/Cargo.toml                     |   1 -
 .../provide_credential/assume_role_with_oidc.rs    |   8 --
 .../aliyun-oss/src/provide_credential/default.rs   |   3 -
 services/aliyun-oss/src/provide_credential/env.rs  |   3 -
 .../aliyun-oss/src/provide_credential/static.rs    |   3 -
 services/aliyun-oss/src/sign_request.rs            |   3 -
 services/aliyun-oss/tests/credential_chain.rs      |   4 -
 services/aws-v4/Cargo.toml                         |   1 -
 services/aws-v4/src/lib.rs                         |   2 -
 .../aws-v4/src/provide_credential/assume_role.rs   |   3 -
 .../assume_role_with_web_identity.rs               |   8 --
 services/aws-v4/src/provide_credential/cognito.rs  |   3 -
 services/aws-v4/src/provide_credential/default.rs  |   3 -
 services/aws-v4/src/provide_credential/ecs.rs      |   3 -
 services/aws-v4/src/provide_credential/env.rs      |   3 -
 services/aws-v4/src/provide_credential/imds.rs     |   3 -
 services/aws-v4/src/provide_credential/process.rs  |   3 -
 services/aws-v4/src/provide_credential/profile.rs  |   3 -
 .../src/provide_credential/s3_express_session.rs   |   9 +-
 services/aws-v4/src/provide_credential/sso.rs      |   3 -
 services/aws-v4/src/provide_credential/static.rs   |   3 -
 services/aws-v4/src/sign_request.rs                |   3 -
 services/azure-storage/Cargo.toml                  |   2 -
 .../src/provide_credential/azure_cli.rs            |   3 -
 .../src/provide_credential/azure_pipelines.rs      |   3 -
 .../src/provide_credential/client_certificate.rs   |   3 -
 .../src/provide_credential/client_secret.rs        |   3 -
 .../src/provide_credential/default.rs              |   7 --
 .../azure-storage/src/provide_credential/env.rs    |   3 -
 .../azure-storage/src/provide_credential/imds.rs   |   3 -
 .../src/provide_credential/static_provider.rs      |   3 -
 .../src/provide_credential/workload_identity.rs    |   3 -
 services/azure-storage/src/sign_request.rs         |   6 --
 .../tests/credential_providers/default.rs          |   3 -
 services/google/Cargo.toml                         |   1 -
 services/google/examples/chain_logging.rs          |   4 -
 services/google/examples/custom_chain.rs           |   6 --
 .../src/provide_credential/authorized_user.rs      |   2 -
 services/google/src/provide_credential/default.rs  |   6 --
 .../src/provide_credential/external_account.rs     |  10 --
 .../impersonated_service_account.rs                |   2 -
 .../src/provide_credential/static_provider.rs      |   2 -
 .../google/src/provide_credential/vm_metadata.rs   |   2 -
 services/google/src/sign_request.rs                |   6 --
 services/huaweicloud-obs/Cargo.toml                |   1 -
 services/huaweicloud-obs/examples/chain_logging.rs |   4 -
 services/huaweicloud-obs/examples/custom_chain.rs  |   6 --
 .../src/provide_credential/config.rs               |   3 -
 .../src/provide_credential/default.rs              |   3 -
 .../huaweicloud-obs/src/provide_credential/env.rs  |   3 -
 .../src/provide_credential/static.rs               |   3 -
 services/huaweicloud-obs/src/sign_request.rs       |   2 -
 services/huaweicloud-obs/tests/credential_chain.rs |   6 --
 services/oracle/Cargo.toml                         |   1 -
 services/oracle/examples/oracle_chain_logging.rs   |   4 -
 services/oracle/src/provide_credential/config.rs   |   3 -
 .../oracle/src/provide_credential/config_file.rs   |   3 -
 services/oracle/src/provide_credential/default.rs  |   3 -
 services/oracle/src/provide_credential/env.rs      |   3 -
 services/oracle/src/provide_credential/static_.rs  |   3 -
 services/oracle/src/sign_request.rs                |   3 -
 services/oracle/tests/credential_chain.rs          |   4 -
 services/tencent-cos/Cargo.toml                    |   1 -
 .../tencent-cos/examples/tencent_chain_logging.rs  |   4 -
 .../assume_role_with_web_identity.rs               |   3 -
 .../tencent-cos/src/provide_credential/config.rs   |   3 -
 .../tencent-cos/src/provide_credential/default.rs  |   3 -
 services/tencent-cos/src/provide_credential/env.rs |   3 -
 .../tencent-cos/src/provide_credential/static.rs   |   3 -
 services/tencent-cos/src/sign_request.rs           |   3 -
 services/tencent-cos/tests/credential_chain.rs     |   6 --
 services/volcengine-tos/Cargo.toml                 |   1 -
 .../src/provide_credential/default.rs              |   3 -
 .../volcengine-tos/src/provide_credential/env.rs   |   3 -
 .../src/provide_credential/static.rs               |   3 -
 services/volcengine-tos/src/sign_request.rs        |   8 +-
 90 files changed, 290 insertions(+), 319 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 681f83d..bd3390c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -84,6 +84,20 @@ jobs:
           rustup target add wasm32-unknown-unknown
           cargo build --target wasm32-unknown-unknown --no-default-features 
--features=aws,azure,aliyun,tencent
 
+  # Keep wasm compatibility checks focused on core traits and supported 
reqsign feature sets.
+  wasm_compat:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 
v6.0.2
+        with:
+          persist-credentials: false
+      - name: Check
+        run: |
+          rustup target add wasm32-unknown-unknown
+          cargo check -p reqsign-core --target wasm32-unknown-unknown
+          cargo build --manifest-path reqsign/Cargo.toml --target 
wasm32-unknown-unknown --no-default-features --features=aws,azure,aliyun,tencent
+          cargo build --manifest-path reqsign/Cargo.toml --target 
wasm32-unknown-unknown --no-default-features 
--features=default-context,aws,azure,aliyun,tencent
+
   unit:
     runs-on: ubuntu-latest
     permissions:
diff --git a/Cargo.toml b/Cargo.toml
index d2cf205..babadd5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,13 +42,13 @@ reqsign-volcengine-tos = { version = "2.0.2", path = 
"services/volcengine-tos" }
 
 # Crates.io dependencies
 anyhow = "1"
-async-trait = "0.1"
 base64 = "0.22"
 bytes = "1"
 criterion = { version = "0.8.1", features = ["async_tokio", "html_reports"] }
 dotenvy = "0.15"
 env_logger = "0.11"
 form_urlencoded = "1"
+futures = "0.3"
 hex = "0.4"
 hmac = "0.12"
 http = "1"
diff --git a/context/command-execute-tokio/Cargo.toml 
b/context/command-execute-tokio/Cargo.toml
index efce491..db39642 100644
--- a/context/command-execute-tokio/Cargo.toml
+++ b/context/command-execute-tokio/Cargo.toml
@@ -29,9 +29,10 @@ repository.workspace = true
 rust-version.workspace = true
 
 [dependencies]
-async-trait = { workspace = true }
 reqsign-core = { workspace = true }
-tokio = { version = "1", features = ["process", "io-util"] }
+
+[target.'cfg(not(target_family = "wasm"))'.dependencies]
+tokio = { version = "1", default-features = false, features = ["process", 
"io-util"] }
 
 [dev-dependencies]
 tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
diff --git a/context/command-execute-tokio/src/lib.rs 
b/context/command-execute-tokio/src/lib.rs
index 6d0a0c2..2cf0aca 100644
--- a/context/command-execute-tokio/src/lib.rs
+++ b/context/command-execute-tokio/src/lib.rs
@@ -77,10 +77,10 @@
 //! # Ok(())
 //! # }
 //! ```
-
-use async_trait::async_trait;
 use reqsign_core::{CommandExecute, CommandOutput, Error, Result};
+#[cfg(not(target_family = "wasm"))]
 use std::process::Stdio;
+#[cfg(not(target_family = "wasm"))]
 use tokio::process::Command;
 
 /// Tokio-based implementation of the `CommandExecute` trait.
@@ -90,7 +90,7 @@ use tokio::process::Command;
 #[derive(Debug, Clone, Copy, Default)]
 pub struct TokioCommandExecute;
 
-#[async_trait]
+#[cfg(not(target_family = "wasm"))]
 impl CommandExecute for TokioCommandExecute {
     async fn command_execute(&self, program: &str, args: &[&str]) -> 
Result<CommandOutput> {
         let output = Command::new(program)
@@ -111,7 +111,16 @@ impl CommandExecute for TokioCommandExecute {
     }
 }
 
-#[cfg(test)]
+#[cfg(target_family = "wasm")]
+impl CommandExecute for TokioCommandExecute {
+    async fn command_execute(&self, _program: &str, _args: &[&str]) -> 
Result<CommandOutput> {
+        Err(Error::unexpected(
+            "TokioCommandExecute is unsupported on wasm targets",
+        ))
+    }
+}
+
+#[cfg(all(test, not(target_family = "wasm")))]
 mod tests {
     use super::*;
 
diff --git a/context/file-read-tokio/Cargo.toml 
b/context/file-read-tokio/Cargo.toml
index 565c1c5..be597bf 100644
--- a/context/file-read-tokio/Cargo.toml
+++ b/context/file-read-tokio/Cargo.toml
@@ -30,7 +30,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 reqsign-core = { workspace = true }
 
 [target.'cfg(not(target_family = "wasm"))'.dependencies]
diff --git a/context/file-read-tokio/src/lib.rs 
b/context/file-read-tokio/src/lib.rs
index 565c1c1..f98c9c8 100644
--- a/context/file-read-tokio/src/lib.rs
+++ b/context/file-read-tokio/src/lib.rs
@@ -63,8 +63,6 @@
 //! # Ok(())
 //! # }
 //! ```
-
-use async_trait::async_trait;
 use reqsign_core::{Error, FileRead, Result};
 
 /// Tokio-based implementation of the `FileRead` trait.
@@ -75,7 +73,6 @@ use reqsign_core::{Error, FileRead, Result};
 pub struct TokioFileRead;
 
 #[cfg(not(target_family = "wasm"))]
-#[async_trait]
 impl FileRead for TokioFileRead {
     async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
         tokio::fs::read(path)
@@ -85,7 +82,6 @@ impl FileRead for TokioFileRead {
 }
 
 #[cfg(target_family = "wasm")]
-#[async_trait]
 impl FileRead for TokioFileRead {
     async fn file_read(&self, _path: &str) -> Result<Vec<u8>> {
         Err(Error::unexpected(
diff --git a/context/http-send-reqwest/Cargo.toml 
b/context/http-send-reqwest/Cargo.toml
index fe20444..fcce246 100644
--- a/context/http-send-reqwest/Cargo.toml
+++ b/context/http-send-reqwest/Cargo.toml
@@ -30,7 +30,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 bytes = { workspace = true }
 http = { workspace = true }
 http-body-util = { version = "0.1.3" }
diff --git a/context/http-send-reqwest/src/lib.rs 
b/context/http-send-reqwest/src/lib.rs
index dfbf029..2e90683 100644
--- a/context/http-send-reqwest/src/lib.rs
+++ b/context/http-send-reqwest/src/lib.rs
@@ -92,8 +92,6 @@
 //! // Use the custom client
 //! let http_send = ReqwestHttpSend::new(client);
 //! ```
-
-use async_trait::async_trait;
 use bytes::Bytes;
 #[cfg(target_arch = "wasm32")]
 use futures_channel::oneshot;
@@ -136,8 +134,6 @@ impl ReqwestHttpSend {
         Self { client }
     }
 }
-
-#[async_trait]
 impl HttpSend for ReqwestHttpSend {
     async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
         let req = Request::try_from(req)
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 33436c0..2d2390b 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -29,10 +29,10 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 base64 = { workspace = true }
 bytes = { workspace = true }
 form_urlencoded = { workspace = true }
+futures = { workspace = true }
 hex = { workspace = true }
 hmac = { workspace = true }
 http = { workspace = true }
diff --git a/core/src/api.rs b/core/src/api.rs
index 31ee603..0d15bb9 100644
--- a/core/src/api.rs
+++ b/core/src/api.rs
@@ -15,8 +15,10 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::{Context, Result};
+use crate::{BoxedFuture, Context, MaybeSend, Result};
 use std::fmt::Debug;
+use std::future::Future;
+use std::ops::Deref;
 use std::time::Duration;
 
 /// SigningCredential is the trait used by signer as the signing credential.
@@ -39,7 +41,6 @@ impl<T: SigningCredential> SigningCredential for Option<T> {
 ///`
 /// Service may require different credential to sign the request, for example, 
AWS require
 /// access key and secret key, while Google Cloud Storage require token.
-#[async_trait::async_trait]
 pub trait ProvideCredential: Debug + Send + Sync + Unpin + 'static {
     /// Credential returned by this loader.
     ///
@@ -47,11 +48,50 @@ pub trait ProvideCredential: Debug + Send + Sync + Unpin + 
'static {
     type Credential: Send + Sync + Unpin + 'static;
 
     /// Load signing credential from current env.
-    async fn provide_credential(&self, ctx: &Context) -> 
Result<Option<Self::Credential>>;
+    fn provide_credential(
+        &self,
+        ctx: &Context,
+    ) -> impl Future<Output = Result<Option<Self::Credential>>> + MaybeSend;
+}
+
+/// ProvideCredentialDyn is the dyn version of [`ProvideCredential`].
+pub trait ProvideCredentialDyn: Debug + Send + Sync + Unpin + 'static {
+    /// Credential returned by this loader.
+    type Credential: Send + Sync + Unpin + 'static;
+
+    /// Dyn version of [`ProvideCredential::provide_credential`].
+    fn provide_credential_dyn<'a>(
+        &'a self,
+        ctx: &'a Context,
+    ) -> BoxedFuture<'a, Result<Option<Self::Credential>>>;
+}
+
+impl<T> ProvideCredentialDyn for T
+where
+    T: ProvideCredential + ?Sized,
+{
+    type Credential = T::Credential;
+
+    fn provide_credential_dyn<'a>(
+        &'a self,
+        ctx: &'a Context,
+    ) -> BoxedFuture<'a, Result<Option<Self::Credential>>> {
+        Box::pin(self.provide_credential(ctx))
+    }
+}
+
+impl<T> ProvideCredential for std::sync::Arc<T>
+where
+    T: ProvideCredentialDyn + ?Sized,
+{
+    type Credential = T::Credential;
+
+    async fn provide_credential(&self, ctx: &Context) -> 
Result<Option<Self::Credential>> {
+        self.deref().provide_credential_dyn(ctx).await
+    }
 }
 
 /// SignRequest is the trait used by signer to build the signing request.
-#[async_trait::async_trait]
 pub trait SignRequest: Debug + Send + Sync + Unpin + 'static {
     /// Credential used by this builder.
     ///
@@ -71,13 +111,64 @@ pub trait SignRequest: Debug + Send + Sync + Unpin + 
'static {
     ///
     /// Implementation details determine how to handle the expiration logic. 
For instance,
     /// AWS uses a query string that includes an `Expires` parameter.
+    fn sign_request<'a>(
+        &'a self,
+        ctx: &'a Context,
+        req: &'a mut http::request::Parts,
+        credential: Option<&'a Self::Credential>,
+        expires_in: Option<Duration>,
+    ) -> impl Future<Output = Result<()>> + MaybeSend + 'a;
+}
+
+/// SignRequestDyn is the dyn version of [`SignRequest`].
+pub trait SignRequestDyn: Debug + Send + Sync + Unpin + 'static {
+    /// Credential used by this builder.
+    type Credential: Send + Sync + Unpin + 'static;
+
+    /// Dyn version of [`SignRequest::sign_request`].
+    fn sign_request_dyn<'a>(
+        &'a self,
+        ctx: &'a Context,
+        req: &'a mut http::request::Parts,
+        credential: Option<&'a Self::Credential>,
+        expires_in: Option<Duration>,
+    ) -> BoxedFuture<'a, Result<()>>;
+}
+
+impl<T> SignRequestDyn for T
+where
+    T: SignRequest + ?Sized,
+{
+    type Credential = T::Credential;
+
+    fn sign_request_dyn<'a>(
+        &'a self,
+        ctx: &'a Context,
+        req: &'a mut http::request::Parts,
+        credential: Option<&'a Self::Credential>,
+        expires_in: Option<Duration>,
+    ) -> BoxedFuture<'a, Result<()>> {
+        Box::pin(self.sign_request(ctx, req, credential, expires_in))
+    }
+}
+
+impl<T> SignRequest for std::sync::Arc<T>
+where
+    T: SignRequestDyn + ?Sized,
+{
+    type Credential = T::Credential;
+
     async fn sign_request(
         &self,
         ctx: &Context,
         req: &mut http::request::Parts,
         credential: Option<&Self::Credential>,
         expires_in: Option<Duration>,
-    ) -> Result<()>;
+    ) -> Result<()> {
+        self.deref()
+            .sign_request_dyn(ctx, req, credential, expires_in)
+            .await
+    }
 }
 
 /// A chain of credential providers that will be tried in order.
@@ -90,7 +181,6 @@ pub trait SignRequest: Debug + Send + Sync + Unpin + 'static 
{
 ///
 /// ```no_run
 /// use reqsign_core::{ProvideCredentialChain, Context, ProvideCredential, 
Result};
-/// use async_trait::async_trait;
 ///
 /// #[derive(Debug)]
 /// struct MyCredential {
@@ -100,7 +190,6 @@ pub trait SignRequest: Debug + Send + Sync + Unpin + 
'static {
 /// #[derive(Debug)]
 /// struct EnvironmentProvider;
 ///
-/// #[async_trait]
 /// impl ProvideCredential for EnvironmentProvider {
 ///     type Credential = MyCredential;
 ///
@@ -118,7 +207,7 @@ pub trait SignRequest: Debug + Send + Sync + Unpin + 
'static {
 /// # }
 /// ```
 pub struct ProvideCredentialChain<C> {
-    providers: Vec<Box<dyn ProvideCredential<Credential = C>>>,
+    providers: Vec<Box<dyn ProvideCredentialDyn<Credential = C>>>,
 }
 
 impl<C> ProvideCredentialChain<C>
@@ -150,7 +239,7 @@ where
     }
 
     /// Create a credential provider chain from a vector of providers.
-    pub fn from_vec(providers: Vec<Box<dyn ProvideCredential<Credential = 
C>>>) -> Self {
+    pub fn from_vec(providers: Vec<Box<dyn ProvideCredentialDyn<Credential = 
C>>>) -> Self {
         Self { providers }
     }
 
@@ -185,7 +274,6 @@ where
     }
 }
 
-#[async_trait::async_trait]
 impl<C> ProvideCredential for ProvideCredentialChain<C>
 where
     C: Send + Sync + Unpin + 'static,
@@ -196,7 +284,7 @@ where
         for provider in &self.providers {
             log::debug!("Trying credential provider: {provider:?}");
 
-            match provider.provide_credential(ctx).await {
+            match provider.provide_credential_dyn(ctx).await {
                 Ok(Some(cred)) => {
                     log::debug!("Successfully loaded credential from provider: 
{provider:?}");
                     return Ok(Some(cred));
diff --git a/core/src/context.rs b/core/src/context.rs
index 4ac3591..1a55b90 100644
--- a/core/src/context.rs
+++ b/core/src/context.rs
@@ -15,10 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::{Error, Result};
+use crate::{BoxedFuture, Error, MaybeSend, Result};
 use bytes::Bytes;
 use std::collections::HashMap;
 use std::fmt::Debug;
+use std::future::Future;
+use std::ops::Deref;
 use std::path::PathBuf;
 use std::sync::Arc;
 
@@ -40,10 +42,10 @@ use std::sync::Arc;
 /// ```
 #[derive(Clone)]
 pub struct Context {
-    fs: Arc<dyn FileRead>,
-    http: Arc<dyn HttpSend>,
+    fs: Arc<dyn FileReadDyn>,
+    http: Arc<dyn HttpSendDyn>,
     env: Arc<dyn Env>,
-    cmd: Arc<dyn CommandExecute>,
+    cmd: Arc<dyn CommandExecuteDyn>,
 }
 
 impl Debug for Context {
@@ -115,7 +117,7 @@ impl Context {
     /// Read the file content entirely in `Vec<u8>`.
     #[inline]
     pub async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
-        self.fs.file_read(path).await
+        self.fs.file_read_dyn(path).await
     }
 
     /// Read the file content entirely in `String`.
@@ -127,7 +129,7 @@ impl Context {
     /// Send http request and return the response.
     #[inline]
     pub async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
-        self.http.http_send(req).await
+        self.http.http_send_dyn(req).await
     }
 
     /// Send http request and return the response as string.
@@ -135,7 +137,7 @@ impl Context {
         &self,
         req: http::Request<Bytes>,
     ) -> Result<http::Response<String>> {
-        let (parts, body) = self.http.http_send(req).await?.into_parts();
+        let (parts, body) = self.http.http_send_dyn(req).await?.into_parts();
         let body = String::from_utf8_lossy(&body).to_string();
         Ok(http::Response::from_parts(parts, body))
     }
@@ -180,27 +182,70 @@ impl Context {
     ///
     /// Returns the command output including exit status, stdout, and stderr.
     pub async fn command_execute(&self, program: &str, args: &[&str]) -> 
Result<CommandOutput> {
-        self.cmd.command_execute(program, args).await
+        self.cmd.command_execute_dyn(program, args).await
     }
 }
 
 /// FileRead is used to read the file content entirely in `Vec<u8>`.
 ///
 /// This could be used by `Load` to load the credential from the file.
-#[async_trait::async_trait]
 pub trait FileRead: Debug + Send + Sync + 'static {
     /// Read the file content entirely in `Vec<u8>`.
-    async fn file_read(&self, path: &str) -> Result<Vec<u8>>;
+    fn file_read(&self, path: &str) -> impl Future<Output = Result<Vec<u8>>> + 
MaybeSend;
+}
+
+/// FileReadDyn is the dyn version of [`FileRead`].
+pub trait FileReadDyn: Debug + Send + Sync + 'static {
+    /// Dyn version of [`FileRead::file_read`].
+    fn file_read_dyn<'a>(&'a self, path: &'a str) -> BoxedFuture<'a, 
Result<Vec<u8>>>;
+}
+
+impl<T: FileRead + ?Sized> FileReadDyn for T {
+    fn file_read_dyn<'a>(&'a self, path: &'a str) -> BoxedFuture<'a, 
Result<Vec<u8>>> {
+        Box::pin(self.file_read(path))
+    }
+}
+
+impl<T: FileReadDyn + ?Sized> FileRead for Arc<T> {
+    async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
+        self.deref().file_read_dyn(path).await
+    }
 }
 
 /// HttpSend is used to send http request during the signing process.
 ///
 /// For example, fetch IMDS token from AWS or OAuth2 refresh token. This trait 
is designed
 /// especially for the signer, please don't use it as a general http client.
-#[async_trait::async_trait]
 pub trait HttpSend: Debug + Send + Sync + 'static {
     /// Send http request and return the response.
-    async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>>;
+    fn http_send(
+        &self,
+        req: http::Request<Bytes>,
+    ) -> impl Future<Output = Result<http::Response<Bytes>>> + MaybeSend;
+}
+
+/// HttpSendDyn is the dyn version of [`HttpSend`].
+pub trait HttpSendDyn: Debug + Send + Sync + 'static {
+    /// Dyn version of [`HttpSend::http_send`].
+    fn http_send_dyn(
+        &self,
+        req: http::Request<Bytes>,
+    ) -> BoxedFuture<'_, Result<http::Response<Bytes>>>;
+}
+
+impl<T: HttpSend + ?Sized> HttpSendDyn for T {
+    fn http_send_dyn(
+        &self,
+        req: http::Request<Bytes>,
+    ) -> BoxedFuture<'_, Result<http::Response<Bytes>>> {
+        Box::pin(self.http_send(req))
+    }
+}
+
+impl<T: HttpSendDyn + ?Sized> HttpSend for Arc<T> {
+    async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
+        self.deref().http_send_dyn(req).await
+    }
 }
 
 /// Permits parameterizing the home functions via the _from variants
@@ -299,10 +344,39 @@ impl CommandOutput {
 /// - Blocking execution for non-async contexts
 /// - WebAssembly environments (returning errors)
 /// - Mock implementations for testing
-#[async_trait::async_trait]
 pub trait CommandExecute: Debug + Send + Sync + 'static {
     /// Execute a command with the given program and arguments.
-    async fn command_execute(&self, program: &str, args: &[&str]) -> 
Result<CommandOutput>;
+    fn command_execute<'a>(
+        &'a self,
+        program: &'a str,
+        args: &'a [&'a str],
+    ) -> impl Future<Output = Result<CommandOutput>> + MaybeSend + 'a;
+}
+
+/// CommandExecuteDyn is the dyn version of [`CommandExecute`].
+pub trait CommandExecuteDyn: Debug + Send + Sync + 'static {
+    /// Dyn version of [`CommandExecute::command_execute`].
+    fn command_execute_dyn<'a>(
+        &'a self,
+        program: &'a str,
+        args: &'a [&'a str],
+    ) -> BoxedFuture<'a, Result<CommandOutput>>;
+}
+
+impl<T: CommandExecute + ?Sized> CommandExecuteDyn for T {
+    fn command_execute_dyn<'a>(
+        &'a self,
+        program: &'a str,
+        args: &'a [&'a str],
+    ) -> BoxedFuture<'a, Result<CommandOutput>> {
+        Box::pin(self.command_execute(program, args))
+    }
+}
+
+impl<T: CommandExecuteDyn + ?Sized> CommandExecute for Arc<T> {
+    async fn command_execute(&self, program: &str, args: &[&str]) -> 
Result<CommandOutput> {
+        self.deref().command_execute_dyn(program, args).await
+    }
 }
 
 /// NoopFileRead is a no-op implementation that always returns an error.
@@ -311,7 +385,6 @@ pub trait CommandExecute: Debug + Send + Sync + 'static {
 #[derive(Debug, Clone, Copy, Default)]
 pub struct NoopFileRead;
 
-#[async_trait::async_trait]
 impl FileRead for NoopFileRead {
     async fn file_read(&self, _path: &str) -> Result<Vec<u8>> {
         Err(Error::unexpected(
@@ -326,7 +399,6 @@ impl FileRead for NoopFileRead {
 #[derive(Debug, Clone, Copy, Default)]
 pub struct NoopHttpSend;
 
-#[async_trait::async_trait]
 impl HttpSend for NoopHttpSend {
     async fn http_send(&self, _req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
         Err(Error::unexpected(
@@ -361,7 +433,6 @@ impl Env for NoopEnv {
 #[derive(Debug, Clone, Copy, Default)]
 pub struct NoopCommandExecute;
 
-#[async_trait::async_trait]
 impl CommandExecute for NoopCommandExecute {
     async fn command_execute(&self, _program: &str, _args: &[&str]) -> 
Result<CommandOutput> {
         Err(Error::unexpected(
diff --git a/core/src/futures_util.rs b/core/src/futures_util.rs
new file mode 100644
index 0000000..1eedff1
--- /dev/null
+++ b/core/src/futures_util.rs
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+/// BoxedFuture is the type alias of [`futures::future::BoxFuture`].
+#[cfg(not(target_arch = "wasm32"))]
+pub type BoxedFuture<'a, T> = futures::future::BoxFuture<'a, T>;
+
+/// BoxedFuture is the type alias of [`futures::future::LocalBoxFuture`].
+#[cfg(target_arch = "wasm32")]
+pub type BoxedFuture<'a, T> = futures::future::LocalBoxFuture<'a, T>;
+
+/// MaybeSend is a marker to determine whether a type is `Send` or not.
+///
+/// [`MaybeSend`] is equivalent to `Send` on non-wasm32 target.
+#[cfg(not(target_arch = "wasm32"))]
+pub trait MaybeSend: Send {}
+
+/// MaybeSend is a marker to determine whether a type is `Send` or not.
+///
+/// [`MaybeSend`] is empty on wasm32 target.
+#[cfg(target_arch = "wasm32")]
+pub trait MaybeSend {}
+
+#[cfg(not(target_arch = "wasm32"))]
+impl<T: Send> MaybeSend for T {}
+
+#[cfg(target_arch = "wasm32")]
+impl<T> MaybeSend for T {}
diff --git a/core/src/lib.rs b/core/src/lib.rs
index d840196..dd827da 100644
--- a/core/src/lib.rs
+++ b/core/src/lib.rs
@@ -32,7 +32,6 @@
 //!
 //! ```no_run
 //! use reqsign_core::{Context, OsEnv, ProvideCredential, Result, SignRequest, 
Signer, SigningCredential};
-//! use async_trait::async_trait;
 //! use http::request::Parts;
 //! use std::time::Duration;
 //!
@@ -53,7 +52,6 @@
 //! #[derive(Debug)]
 //! struct MyLoader;
 //!
-//! #[async_trait]
 //! impl ProvideCredential for MyLoader {
 //!     type Credential = MyCredential;
 //!
@@ -69,7 +67,6 @@
 //! #[derive(Debug)]
 //! struct MyBuilder;
 //!
-//! #[async_trait]
 //! impl SignRequest for MyBuilder {
 //!     type Credential = MyCredential;
 //!
@@ -88,13 +85,11 @@
 //!
 //! # async fn example() -> Result<()> {
 //! # use reqsign_core::{FileRead, HttpSend};
-//! # use async_trait::async_trait;
 //! # use bytes::Bytes;
 //! #
 //! # // Mock implementations for the example
 //! # #[derive(Debug, Clone)]
 //! # struct MockFileRead;
-//! # #[async_trait]
 //! # impl FileRead for MockFileRead {
 //! #     async fn file_read(&self, _path: &str) -> Result<Vec<u8>> {
 //! #         Ok(vec![])
@@ -103,7 +98,6 @@
 //! #
 //! # #[derive(Debug, Clone)]
 //! # struct MockHttpSend;
-//! # #[async_trait]
 //! # impl HttpSend for MockHttpSend {
 //! #     async fn http_send(&self, _req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
 //! #         Ok(http::Response::builder().status(200).body(Bytes::new())?)
@@ -157,19 +151,25 @@
 
 /// Error types for reqsign operations
 pub mod error;
+mod futures_util;
 pub mod hash;
 pub mod time;
 pub mod utils;
 
 pub use error::{Error, ErrorKind, Result};
+pub use futures_util::BoxedFuture;
+pub use futures_util::MaybeSend;
 
 mod context;
 pub use context::CommandExecute;
+pub use context::CommandExecuteDyn;
 pub use context::CommandOutput;
 pub use context::Context;
 pub use context::Env;
 pub use context::FileRead;
+pub use context::FileReadDyn;
 pub use context::HttpSend;
+pub use context::HttpSendDyn;
 pub use context::NoopCommandExecute;
 pub use context::NoopEnv;
 pub use context::NoopFileRead;
@@ -178,7 +178,12 @@ pub use context::OsEnv;
 pub use context::StaticEnv;
 
 mod api;
-pub use api::{ProvideCredential, ProvideCredentialChain, SignRequest, 
SigningCredential};
+pub use api::ProvideCredential;
+pub use api::ProvideCredentialChain;
+pub use api::ProvideCredentialDyn;
+pub use api::SignRequest;
+pub use api::SignRequestDyn;
+pub use api::SigningCredential;
 mod request;
 pub use request::{SigningMethod, SigningRequest};
 mod signer;
diff --git a/core/src/signer.rs b/core/src/signer.rs
index 6ba2508..0d55fa6 100644
--- a/core/src/signer.rs
+++ b/core/src/signer.rs
@@ -15,7 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::{Context, Error, ProvideCredential, Result, SignRequest, 
SigningCredential};
+use crate::Context;
+use crate::Error;
+use crate::ProvideCredential;
+use crate::ProvideCredentialDyn;
+use crate::Result;
+use crate::SignRequest;
+use crate::SignRequestDyn;
+use crate::SigningCredential;
 use std::any::type_name;
 use std::sync::{Arc, Mutex};
 use std::time::Duration;
@@ -24,8 +31,8 @@ use std::time::Duration;
 #[derive(Clone, Debug)]
 pub struct Signer<K: SigningCredential> {
     ctx: Context,
-    loader: Arc<dyn ProvideCredential<Credential = K>>,
-    builder: Arc<dyn SignRequest<Credential = K>>,
+    loader: Arc<dyn ProvideCredentialDyn<Credential = K>>,
+    builder: Arc<dyn SignRequestDyn<Credential = K>>,
     credential: Arc<Mutex<Option<K>>>,
 }
 
@@ -77,7 +84,7 @@ impl<K: SigningCredential> Signer<K> {
         let credential = if credential.is_valid() {
             credential
         } else {
-            let ctx = self.loader.provide_credential(&self.ctx).await?;
+            let ctx = self.loader.provide_credential_dyn(&self.ctx).await?;
             *self.credential.lock().expect("lock poisoned") = ctx.clone();
             ctx
         };
@@ -88,7 +95,7 @@ impl<K: SigningCredential> Signer<K> {
         })?;
 
         self.builder
-            .sign_request(&self.ctx, req, Some(credential_ref), expires_in)
+            .sign_request_dyn(&self.ctx, req, Some(credential_ref), expires_in)
             .await
     }
 }
diff --git a/services/aliyun-oss/Cargo.toml b/services/aliyun-oss/Cargo.toml
index 7c1a0a4..ce18ded 100644
--- a/services/aliyun-oss/Cargo.toml
+++ b/services/aliyun-oss/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 form_urlencoded = { workspace = true }
 http = { workspace = true }
 log = { workspace = true }
diff --git 
a/services/aliyun-oss/src/provide_credential/assume_role_with_oidc.rs 
b/services/aliyun-oss/src/provide_credential/assume_role_with_oidc.rs
index d340ed3..29a6b43 100644
--- a/services/aliyun-oss/src/provide_credential/assume_role_with_oidc.rs
+++ b/services/aliyun-oss/src/provide_credential/assume_role_with_oidc.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use form_urlencoded::Serializer;
 use reqsign_core::Result;
 use reqsign_core::time::Timestamp;
@@ -79,8 +78,6 @@ impl AssumeRoleWithOidcCredentialProvider {
             .unwrap_or_else(|| "reqsign".to_string())
     }
 }
-
-#[async_trait]
 impl ProvideCredential for AssumeRoleWithOidcCredentialProvider {
     type Credential = Credential;
 
@@ -168,7 +165,6 @@ struct AssumeRoleWithOidcCredentials {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use async_trait::async_trait;
     use bytes::Bytes;
     use reqsign_core::StaticEnv;
     use reqsign_core::{Context, FileRead, HttpSend};
@@ -239,8 +235,6 @@ mod tests {
         expected_path: String,
         content: Vec<u8>,
     }
-
-    #[async_trait]
     impl FileRead for TestFileRead {
         async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
             assert_eq!(path, self.expected_path);
@@ -266,8 +260,6 @@ mod tests {
             self.uri.lock().unwrap().clone()
         }
     }
-
-    #[async_trait]
     impl HttpSend for CaptureHttpSend {
         async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
             *self.uri.lock().unwrap() = Some(req.uri().to_string());
diff --git a/services/aliyun-oss/src/provide_credential/default.rs 
b/services/aliyun-oss/src/provide_credential/default.rs
index dc32732..fb1b3c8 100644
--- a/services/aliyun-oss/src/provide_credential/default.rs
+++ b/services/aliyun-oss/src/provide_credential/default.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::provide_credential::{AssumeRoleWithOidcCredentialProvider, 
EnvCredentialProvider};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 
 /// DefaultCredentialProvider is a loader that will try to load credential via 
default chains.
@@ -147,8 +146,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aliyun-oss/src/provide_credential/env.rs 
b/services/aliyun-oss/src/provide_credential/env.rs
index 56d700c..d44020d 100644
--- a/services/aliyun-oss/src/provide_credential/env.rs
+++ b/services/aliyun-oss/src/provide_credential/env.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// EnvCredentialProvider loads Aliyun credentials from environment variables.
@@ -34,8 +33,6 @@ impl EnvCredentialProvider {
         Self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aliyun-oss/src/provide_credential/static.rs 
b/services/aliyun-oss/src/provide_credential/static.rs
index e47e41e..710a33d 100644
--- a/services/aliyun-oss/src/provide_credential/static.rs
+++ b/services/aliyun-oss/src/provide_credential/static.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// StaticCredentialProvider provides static Aliyun credentials.
@@ -46,8 +45,6 @@ impl StaticCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aliyun-oss/src/sign_request.rs 
b/services/aliyun-oss/src/sign_request.rs
index 7884ad8..35192dd 100644
--- a/services/aliyun-oss/src/sign_request.rs
+++ b/services/aliyun-oss/src/sign_request.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::credential::Credential;
-use async_trait::async_trait;
 use http::HeaderValue;
 use http::header::{AUTHORIZATION, CONTENT_TYPE, DATE};
 use percent_encoding::utf8_percent_encode;
@@ -63,8 +62,6 @@ impl RequestSigner {
         self.time.unwrap_or_else(Timestamp::now)
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
diff --git a/services/aliyun-oss/tests/credential_chain.rs 
b/services/aliyun-oss/tests/credential_chain.rs
index c036258..e9f3489 100644
--- a/services/aliyun-oss/tests/credential_chain.rs
+++ b/services/aliyun-oss/tests/credential_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Integration tests for ProvideCredentialChain with Aliyun OSS
-
-use async_trait::async_trait;
 use reqsign_aliyun_oss::{Credential, EnvCredentialProvider};
 use reqsign_core::ProvideCredentialChain;
 use reqsign_core::{Context, OsEnv, ProvideCredential, Result};
@@ -32,8 +30,6 @@ struct CountingProvider {
     return_credential: bool,
     call_count: Arc<std::sync::Mutex<usize>>,
 }
-
-#[async_trait]
 impl ProvideCredential for CountingProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/Cargo.toml b/services/aws-v4/Cargo.toml
index f816665..7879304 100644
--- a/services/aws-v4/Cargo.toml
+++ b/services/aws-v4/Cargo.toml
@@ -32,7 +32,6 @@ name = "aws"
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 bytes = "1.7.2"
 form_urlencoded = { workspace = true }
 http = { workspace = true }
diff --git a/services/aws-v4/src/lib.rs b/services/aws-v4/src/lib.rs
index be449f1..9d3eb26 100644
--- a/services/aws-v4/src/lib.rs
+++ b/services/aws-v4/src/lib.rs
@@ -106,12 +106,10 @@
 //!
 //! ```no_run
 //! use reqsign_core::{ProvideCredential, Context, Result};
-//! use async_trait::async_trait;
 //!
 //! # #[derive(Debug)]
 //! # struct MyCredentialProvider;
 //! # type Credential = reqsign_aws_v4::Credential;
-//! #[async_trait]
 //! impl ProvideCredential for MyCredentialProvider {
 //!     type Credential = Credential;
 //!     
diff --git a/services/aws-v4/src/provide_credential/assume_role.rs 
b/services/aws-v4/src/provide_credential/assume_role.rs
index 9a47212..7150c79 100644
--- a/services/aws-v4/src/provide_credential/assume_role.rs
+++ b/services/aws-v4/src/provide_credential/assume_role.rs
@@ -19,7 +19,6 @@ use crate::EMPTY_STRING_SHA256;
 use crate::constants::X_AMZ_CONTENT_SHA_256;
 use crate::credential::Credential;
 use crate::provide_credential::utils::{parse_sts_error, sts_endpoint};
-use async_trait::async_trait;
 use bytes::Bytes;
 use form_urlencoded::Serializer;
 use quick_xml::de;
@@ -153,8 +152,6 @@ impl AssumeRoleCredentialProvider {
         Some(provider)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for AssumeRoleCredentialProvider {
     type Credential = Credential;
 
diff --git 
a/services/aws-v4/src/provide_credential/assume_role_with_web_identity.rs 
b/services/aws-v4/src/provide_credential/assume_role_with_web_identity.rs
index d3e73ae..6109bda 100644
--- a/services/aws-v4/src/provide_credential/assume_role_with_web_identity.rs
+++ b/services/aws-v4/src/provide_credential/assume_role_with_web_identity.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::provide_credential::utils::{parse_sts_error, sts_endpoint};
-use async_trait::async_trait;
 use bytes::Bytes;
 use form_urlencoded::Serializer;
 use quick_xml::de;
@@ -114,8 +113,6 @@ impl AssumeRoleWithWebIdentityCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for AssumeRoleWithWebIdentityCredentialProvider {
     type Credential = Credential;
 
@@ -305,7 +302,6 @@ impl Debug for AssumeRoleWithWebIdentityCredentials {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use async_trait::async_trait;
     use reqsign_core::{FileRead, HttpSend, StaticEnv};
     use std::collections::HashMap;
     use std::sync::{Arc, Mutex};
@@ -354,8 +350,6 @@ mod tests {
         expected_path: String,
         content: Vec<u8>,
     }
-
-    #[async_trait]
     impl FileRead for TestFileRead {
         async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
             assert_eq!(path, self.expected_path);
@@ -381,8 +375,6 @@ mod tests {
             self.uri.lock().unwrap().clone()
         }
     }
-
-    #[async_trait]
     impl HttpSend for CaptureHttpSend {
         async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
             *self.uri.lock().unwrap() = Some(req.uri().to_string());
diff --git a/services/aws-v4/src/provide_credential/cognito.rs 
b/services/aws-v4/src/provide_credential/cognito.rs
index 1de3730..43b0438 100644
--- a/services/aws-v4/src/provide_credential/cognito.rs
+++ b/services/aws-v4/src/provide_credential/cognito.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use http::{Method, Request, StatusCode};
 use log::debug;
 use reqsign_core::time::Timestamp;
@@ -258,8 +257,6 @@ struct CognitoCredentials {
     session_token: String,
     expiration: i64,
 }
-
-#[async_trait]
 impl ProvideCredential for CognitoIdentityCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/default.rs 
b/services/aws-v4/src/provide_credential/default.rs
index ca3cc46..adde860 100644
--- a/services/aws-v4/src/provide_credential/default.rs
+++ b/services/aws-v4/src/provide_credential/default.rs
@@ -22,7 +22,6 @@ use crate::provide_credential::{
 };
 #[cfg(not(target_arch = "wasm32"))]
 use crate::provide_credential::{ProcessCredentialProvider, 
SSOCredentialProvider};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 
 /// DefaultCredentialProvider is a loader that will try to load credential via 
default chains.
@@ -329,8 +328,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/ecs.rs 
b/services/aws-v4/src/provide_credential/ecs.rs
index ee25bb5..70ff3a2 100644
--- a/services/aws-v4/src/provide_credential/ecs.rs
+++ b/services/aws-v4/src/provide_credential/ecs.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use http::{HeaderValue, Method, Request, StatusCode};
 use log::debug;
 use reqsign_core::{Context, Error, ProvideCredential, Result};
@@ -216,8 +215,6 @@ struct ECSCredentialResponse {
     token: String,
     expiration: String,
 }
-
-#[async_trait]
 impl ProvideCredential for ECSCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/env.rs 
b/services/aws-v4/src/provide_credential/env.rs
index daa8fb3..db284fa 100644
--- a/services/aws-v4/src/provide_credential/env.rs
+++ b/services/aws-v4/src/provide_credential/env.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// EnvCredentialProvider loads AWS credentials from environment variables.
@@ -34,8 +33,6 @@ impl EnvCredentialProvider {
         Self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/imds.rs 
b/services/aws-v4/src/provide_credential/imds.rs
index 1ec8bd2..31fd03d 100644
--- a/services/aws-v4/src/provide_credential/imds.rs
+++ b/services/aws-v4/src/provide_credential/imds.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::provide_credential::utils::parse_imds_error;
-use async_trait::async_trait;
 use bytes::Bytes;
 use http::Method;
 use http::header::CONTENT_LENGTH;
@@ -115,8 +114,6 @@ impl IMDSv2CredentialProvider {
         Ok(ec2_token)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for IMDSv2CredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/process.rs 
b/services/aws-v4/src/provide_credential/process.rs
index d3383d1..2fe482f 100644
--- a/services/aws-v4/src/provide_credential/process.rs
+++ b/services/aws-v4/src/provide_credential/process.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use ini::Ini;
 use log::debug;
 use reqsign_core::{Context, Error, ProvideCredential, Result};
@@ -194,8 +193,6 @@ struct ProcessCredentialOutput {
     #[serde(default)]
     expiration: Option<String>,
 }
-
-#[async_trait]
 impl ProvideCredential for ProcessCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/profile.rs 
b/services/aws-v4/src/provide_credential/profile.rs
index 09806d7..d795c8d 100644
--- a/services/aws-v4/src/provide_credential/profile.rs
+++ b/services/aws-v4/src/provide_credential/profile.rs
@@ -18,7 +18,6 @@
 use crate::Credential;
 #[cfg(not(target_arch = "wasm32"))]
 use crate::constants::*;
-use async_trait::async_trait;
 #[cfg(not(target_arch = "wasm32"))]
 use ini::Ini;
 #[cfg(not(target_arch = "wasm32"))]
@@ -202,8 +201,6 @@ impl ProfileCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for ProfileCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/s3_express_session.rs 
b/services/aws-v4/src/provide_credential/s3_express_session.rs
index 31706f2..4c1be89 100644
--- a/services/aws-v4/src/provide_credential/s3_express_session.rs
+++ b/services/aws-v4/src/provide_credential/s3_express_session.rs
@@ -16,11 +16,10 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use bytes::Bytes;
 use http::{Method, Request, header};
 use log::debug;
-use reqsign_core::{Context, Error, ProvideCredential, Result, SignRequest};
+use reqsign_core::{Context, Error, ProvideCredential, ProvideCredentialDyn, 
Result, SignRequest};
 use serde::Deserialize;
 
 /// S3 Express One Zone session provider that creates session credentials.
@@ -55,7 +54,7 @@ use serde::Deserialize;
 #[derive(Debug)]
 pub struct S3ExpressSessionProvider {
     bucket: String,
-    base_provider: Box<dyn ProvideCredential<Credential = Credential>>,
+    base_provider: Box<dyn ProvideCredentialDyn<Credential = Credential>>,
 }
 
 #[derive(Debug, Deserialize)]
@@ -198,8 +197,6 @@ impl S3ExpressSessionProvider {
         Ok(region.to_string())
     }
 }
-
-#[async_trait]
 impl ProvideCredential for S3ExpressSessionProvider {
     type Credential = Credential;
 
@@ -207,7 +204,7 @@ impl ProvideCredential for S3ExpressSessionProvider {
         debug!("Creating S3 Express session for bucket: {}", self.bucket);
 
         // Get base credentials - required for S3 Express
-        let base_cred = self.base_provider.provide_credential(ctx).await?
+        let base_cred = self.base_provider.provide_credential_dyn(ctx).await?
             .ok_or_else(|| {
                 Error::unexpected(
                     "No base credentials found. S3 Express requires valid AWS 
credentials to create sessions"
diff --git a/services/aws-v4/src/provide_credential/sso.rs 
b/services/aws-v4/src/provide_credential/sso.rs
index 3237f2c..ccc1968 100644
--- a/services/aws-v4/src/provide_credential/sso.rs
+++ b/services/aws-v4/src/provide_credential/sso.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use http::{Method, Request, StatusCode};
 use ini::Ini;
 use log::{debug, warn};
@@ -325,8 +324,6 @@ struct RoleCredentials {
     session_token: String,
     expiration: i64,
 }
-
-#[async_trait]
 impl ProvideCredential for SSOCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/provide_credential/static.rs 
b/services/aws-v4/src/provide_credential/static.rs
index 52e2a30..26a8749 100644
--- a/services/aws-v4/src/provide_credential/static.rs
+++ b/services/aws-v4/src/provide_credential/static.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// StaticCredentialProvider provides static AWS credentials.
@@ -46,8 +45,6 @@ impl StaticCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/aws-v4/src/sign_request.rs 
b/services/aws-v4/src/sign_request.rs
index 49144ad..6ac2317 100644
--- a/services/aws-v4/src/sign_request.rs
+++ b/services/aws-v4/src/sign_request.rs
@@ -20,7 +20,6 @@ use crate::constants::{
     AWS_QUERY_ENCODE_SET, X_AMZ_CONTENT_SHA_256, X_AMZ_DATE, 
X_AMZ_S3_SESSION_TOKEN,
     X_AMZ_SECURITY_TOKEN,
 };
-use async_trait::async_trait;
 use http::request::Parts;
 use http::{HeaderValue, header};
 use log::debug;
@@ -65,8 +64,6 @@ impl RequestSigner {
         self
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
diff --git a/services/azure-storage/Cargo.toml 
b/services/azure-storage/Cargo.toml
index 706d27f..d3c3bc2 100644
--- a/services/azure-storage/Cargo.toml
+++ b/services/azure-storage/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 base64 = { workspace = true }
 bytes = { workspace = true }
 form_urlencoded = { workspace = true }
@@ -46,7 +45,6 @@ pem = "3.0"
 rsa = { workspace = true }
 
 [dev-dependencies]
-async-trait = { workspace = true }
 env_logger = { workspace = true }
 reqsign-command-execute-tokio = { workspace = true }
 reqsign-file-read-tokio = { workspace = true }
diff --git a/services/azure-storage/src/provide_credential/azure_cli.rs 
b/services/azure-storage/src/provide_credential/azure_cli.rs
index abe7d84..55a2d8d 100644
--- a/services/azure-storage/src/provide_credential/azure_cli.rs
+++ b/services/azure-storage/src/provide_credential/azure_cli.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::credential::Credential;
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential};
 use serde::Deserialize;
@@ -79,8 +78,6 @@ struct AzureCliToken {
     #[allow(dead_code)]
     token_type: String,
 }
-
-#[async_trait]
 impl ProvideCredential for AzureCliCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/azure_pipelines.rs 
b/services/azure-storage/src/provide_credential/azure_pipelines.rs
index fef7912..5872992 100644
--- a/services/azure-storage/src/provide_credential/azure_pipelines.rs
+++ b/services/azure-storage/src/provide_credential/azure_pipelines.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::credential::Credential;
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential};
 use serde::Deserialize;
@@ -167,8 +166,6 @@ struct TokenResponse {
     #[allow(dead_code)]
     token_type: String,
 }
-
-#[async_trait]
 impl ProvideCredential for AzurePipelinesCredentialProvider {
     type Credential = Credential;
 
diff --git 
a/services/azure-storage/src/provide_credential/client_certificate.rs 
b/services/azure-storage/src/provide_credential/client_certificate.rs
index 3bbb4f1..6715b1e 100644
--- a/services/azure-storage/src/provide_credential/client_certificate.rs
+++ b/services/azure-storage/src/provide_credential/client_certificate.rs
@@ -19,7 +19,6 @@ use std::collections::HashMap;
 use std::time::{Duration, SystemTime, UNIX_EPOCH};
 
 use crate::credential::Credential;
-use async_trait::async_trait;
 use base64::Engine;
 use base64::engine::general_purpose::URL_SAFE_NO_PAD;
 use jsonwebtoken::{Algorithm, EncodingKey, Header};
@@ -265,8 +264,6 @@ struct TokenResponse {
     #[allow(dead_code)]
     token_type: String,
 }
-
-#[async_trait]
 impl ProvideCredential for ClientCertificateCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/client_secret.rs 
b/services/azure-storage/src/provide_credential/client_secret.rs
index b46922d..24e14eb 100644
--- a/services/azure-storage/src/provide_credential/client_secret.rs
+++ b/services/azure-storage/src/provide_credential/client_secret.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
 use std::time::Duration;
@@ -52,8 +51,6 @@ impl ClientSecretCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for ClientSecretCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/default.rs 
b/services/azure-storage/src/provide_credential/default.rs
index 0e698fa..5a00a7f 100644
--- a/services/azure-storage/src/provide_credential/default.rs
+++ b/services/azure-storage/src/provide_credential/default.rs
@@ -22,7 +22,6 @@ use crate::provide_credential::{
     AzurePipelinesCredentialProvider, ClientSecretCredentialProvider, 
EnvCredentialProvider,
     ImdsCredentialProvider, WorkloadIdentityCredentialProvider,
 };
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 
 /// Default loader that tries multiple credential sources in order.
@@ -327,8 +326,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
@@ -406,8 +403,6 @@ mod tests {
     // Mock implementations for testing
     #[derive(Debug)]
     struct MockFileRead;
-
-    #[async_trait]
     impl reqsign_core::FileRead for MockFileRead {
         async fn file_read(&self, _path: &str) -> Result<Vec<u8>> {
             Ok(Vec::new())
@@ -416,8 +411,6 @@ mod tests {
 
     #[derive(Debug)]
     struct MockHttpSend;
-
-    #[async_trait]
     impl reqsign_core::HttpSend for MockHttpSend {
         async fn http_send(
             &self,
diff --git a/services/azure-storage/src/provide_credential/env.rs 
b/services/azure-storage/src/provide_credential/env.rs
index 411d99d..8be2368 100644
--- a/services/azure-storage/src/provide_credential/env.rs
+++ b/services/azure-storage/src/provide_credential/env.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential};
 
 use crate::credential::Credential;
@@ -28,8 +27,6 @@ impl EnvCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/imds.rs 
b/services/azure-storage/src/provide_credential/imds.rs
index 5c24959..e91b791 100644
--- a/services/azure-storage/src/provide_credential/imds.rs
+++ b/services/azure-storage/src/provide_credential/imds.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
 use std::time::Duration;
@@ -44,8 +43,6 @@ impl ImdsCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for ImdsCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/static_provider.rs 
b/services/azure-storage/src/provide_credential/static_provider.rs
index 7d559dd..159a5e7 100644
--- a/services/azure-storage/src/provide_credential/static_provider.rs
+++ b/services/azure-storage/src/provide_credential/static_provider.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential};
 
 use crate::credential::Credential;
@@ -44,8 +43,6 @@ impl StaticCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/provide_credential/workload_identity.rs 
b/services/azure-storage/src/provide_credential/workload_identity.rs
index eeea220..44ecca6 100644
--- a/services/azure-storage/src/provide_credential/workload_identity.rs
+++ b/services/azure-storage/src/provide_credential/workload_identity.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
 use std::time::Duration;
@@ -45,8 +44,6 @@ impl WorkloadIdentityCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for WorkloadIdentityCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/azure-storage/src/sign_request.rs 
b/services/azure-storage/src/sign_request.rs
index ce0ed7f..1de4b18 100644
--- a/services/azure-storage/src/sign_request.rs
+++ b/services/azure-storage/src/sign_request.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::constants::*;
-use async_trait::async_trait;
 use http::request::Parts;
 use http::{HeaderValue, header};
 use log::debug;
@@ -181,8 +180,6 @@ impl Default for RequestSigner {
         Self::new()
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
@@ -677,7 +674,6 @@ fn canonicalize_resource(ctx: &mut SigningRequest, 
account_name: &str) -> String
 #[cfg(test)]
 mod tests {
     use super::*;
-    use async_trait::async_trait;
     use bytes::Bytes;
     use http::Request;
     use reqsign_core::{Context, HttpSend, OsEnv};
@@ -806,8 +802,6 @@ mod tests {
 
     #[derive(Debug)]
     struct MockUserDelegationHttpSend;
-
-    #[async_trait]
     impl HttpSend for MockUserDelegationHttpSend {
         async fn http_send(
             &self,
diff --git a/services/azure-storage/tests/credential_providers/default.rs 
b/services/azure-storage/tests/credential_providers/default.rs
index 31b5d9c..e76b5eb 100644
--- a/services/azure-storage/tests/credential_providers/default.rs
+++ b/services/azure-storage/tests/credential_providers/default.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_azure_storage::{Credential, DefaultCredentialProvider};
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -33,8 +32,6 @@ struct CountingProvider {
     return_credential: Option<Credential>,
     call_count: Arc<std::sync::Mutex<usize>>,
 }
-
-#[async_trait]
 impl ProvideCredential for CountingProvider {
     type Credential = Credential;
 
diff --git a/services/google/Cargo.toml b/services/google/Cargo.toml
index c858ae0..33d0a8f 100644
--- a/services/google/Cargo.toml
+++ b/services/google/Cargo.toml
@@ -27,7 +27,6 @@ repository.workspace = true
 rust-version.workspace = true
 
 [dependencies]
-async-trait = { workspace = true }
 form_urlencoded = { workspace = true }
 http = { workspace = true }
 jsonwebtoken = { workspace = true }
diff --git a/services/google/examples/chain_logging.rs 
b/services/google/examples/chain_logging.rs
index 1a91f5b..196ab3f 100644
--- a/services/google/examples/chain_logging.rs
+++ b/services/google/examples/chain_logging.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of using ProvideCredentialChain with logging to see credential 
resolution
-
-use async_trait::async_trait;
 use log::{debug, info};
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -39,8 +37,6 @@ impl<P> LoggingProvider<P> {
         }
     }
 }
-
-#[async_trait]
 impl<P> ProvideCredential for LoggingProvider<P>
 where
     P: ProvideCredential<Credential = Credential> + Send + Sync,
diff --git a/services/google/examples/custom_chain.rs 
b/services/google/examples/custom_chain.rs
index d73d83c..6ad9153 100644
--- a/services/google/examples/custom_chain.rs
+++ b/services/google/examples/custom_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of building a custom credential chain with specific providers
-
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 use reqsign_file_read_tokio::TokioFileRead;
 use reqsign_google::{Credential, ServiceAccount, Token};
@@ -48,8 +46,6 @@ impl StaticCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
@@ -61,8 +57,6 @@ impl ProvideCredential for StaticCredentialProvider {
 /// Environment-based provider (simplified example)
 #[derive(Debug)]
 struct EnvCredentialProvider;
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/provide_credential/authorized_user.rs 
b/services/google/src/provide_credential/authorized_user.rs
index c37e15c..ac74e25 100644
--- a/services/google/src/provide_credential/authorized_user.rs
+++ b/services/google/src/provide_credential/authorized_user.rs
@@ -53,8 +53,6 @@ impl AuthorizedUserCredentialProvider {
         Self { oauth2_credentials }
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for AuthorizedUserCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/provide_credential/default.rs 
b/services/google/src/provide_credential/default.rs
index 7b74479..cf5d570 100644
--- a/services/google/src/provide_credential/default.rs
+++ b/services/google/src/provide_credential/default.rs
@@ -112,8 +112,6 @@ impl DefaultCredentialProvider {
             .build()
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
@@ -139,8 +137,6 @@ impl EnvAdcCredentialProvider {
         self
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for EnvAdcCredentialProvider {
     type Credential = Credential;
 
@@ -178,8 +174,6 @@ impl WellKnownAdcCredentialProvider {
         self
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for WellKnownAdcCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/provide_credential/external_account.rs 
b/services/google/src/provide_credential/external_account.rs
index 91adcd5..dee05c6 100644
--- a/services/google/src/provide_credential/external_account.rs
+++ b/services/google/src/provide_credential/external_account.rs
@@ -287,8 +287,6 @@ impl ExternalAccountCredentialProvider {
         }))
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for ExternalAccountCredentialProvider {
     type Credential = Credential;
 
@@ -355,8 +353,6 @@ fn resolve_template(ctx: &Context, input: &str) -> 
Result<String> {
 #[cfg(test)]
 mod tests {
     use super::*;
-
-    use async_trait::async_trait;
     use bytes::Bytes;
     use http::header::{AUTHORIZATION, CONTENT_TYPE};
     use reqsign_core::{Env, FileRead, HttpSend};
@@ -400,8 +396,6 @@ mod tests {
             self
         }
     }
-
-    #[async_trait]
     impl FileRead for MockFileRead {
         async fn file_read(&self, path: &str) -> Result<Vec<u8>> {
             self.files.get(path).cloned().ok_or_else(|| {
@@ -419,8 +413,6 @@ mod tests {
         expected_subject_token_type: String,
         access_token: String,
     }
-
-    #[async_trait]
     impl HttpSend for CaptureStsHttpSend {
         async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
             assert_eq!(req.method(), http::Method::POST);
@@ -480,8 +472,6 @@ mod tests {
         expected_post_url: String,
         expected_subject_token: String,
     }
-
-    #[async_trait]
     impl HttpSend for UrlThenStsHttpSend {
         async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
             match *req.method() {
diff --git 
a/services/google/src/provide_credential/impersonated_service_account.rs 
b/services/google/src/provide_credential/impersonated_service_account.rs
index 5d57c09..c5e4725 100644
--- a/services/google/src/provide_credential/impersonated_service_account.rs
+++ b/services/google/src/provide_credential/impersonated_service_account.rs
@@ -206,8 +206,6 @@ impl ImpersonatedServiceAccountCredentialProvider {
         })
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for ImpersonatedServiceAccountCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/provide_credential/static_provider.rs 
b/services/google/src/provide_credential/static_provider.rs
index b893bda..f7ea3e7 100644
--- a/services/google/src/provide_credential/static_provider.rs
+++ b/services/google/src/provide_credential/static_provider.rs
@@ -64,8 +64,6 @@ impl StaticCredentialProvider {
         self
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/provide_credential/vm_metadata.rs 
b/services/google/src/provide_credential/vm_metadata.rs
index ece9c62..b850e2d 100644
--- a/services/google/src/provide_credential/vm_metadata.rs
+++ b/services/google/src/provide_credential/vm_metadata.rs
@@ -55,8 +55,6 @@ impl VmMetadataCredentialProvider {
         self
     }
 }
-
-#[async_trait::async_trait]
 impl ProvideCredential for VmMetadataCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/google/src/sign_request.rs 
b/services/google/src/sign_request.rs
index 1062bcc..420036b 100644
--- a/services/google/src/sign_request.rs
+++ b/services/google/src/sign_request.rs
@@ -357,8 +357,6 @@ impl RequestSigner {
         Ok(req)
     }
 }
-
-#[async_trait::async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
@@ -560,8 +558,6 @@ fn canonicalize_query(
 #[cfg(test)]
 mod tests {
     use super::*;
-
-    use async_trait::async_trait;
     use bytes::Bytes;
     use http::header;
     use reqsign_core::HttpSend;
@@ -576,8 +572,6 @@ mod tests {
     struct MockHttpSend {
         recorded: Arc<Mutex<Recorded>>,
     }
-
-    #[async_trait]
     impl HttpSend for MockHttpSend {
         async fn http_send(&self, req: http::Request<Bytes>) -> 
Result<http::Response<Bytes>> {
             assert_eq!(req.method(), http::Method::POST);
diff --git a/services/huaweicloud-obs/Cargo.toml 
b/services/huaweicloud-obs/Cargo.toml
index 8e866a7..4d07781 100644
--- a/services/huaweicloud-obs/Cargo.toml
+++ b/services/huaweicloud-obs/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 http = { workspace = true }
 log = { workspace = true }
 percent-encoding = { workspace = true }
diff --git a/services/huaweicloud-obs/examples/chain_logging.rs 
b/services/huaweicloud-obs/examples/chain_logging.rs
index bfeb09a..0e8d54f 100644
--- a/services/huaweicloud-obs/examples/chain_logging.rs
+++ b/services/huaweicloud-obs/examples/chain_logging.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of using ProvideCredentialChain with logging to see credential 
resolution
-
-use async_trait::async_trait;
 use log::{debug, info};
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -41,8 +39,6 @@ impl<P> LoggingProvider<P> {
         }
     }
 }
-
-#[async_trait]
 impl<P> ProvideCredential for LoggingProvider<P>
 where
     P: ProvideCredential<Credential = Credential> + Send + Sync,
diff --git a/services/huaweicloud-obs/examples/custom_chain.rs 
b/services/huaweicloud-obs/examples/custom_chain.rs
index 49ac6be..fdc6fa6 100644
--- a/services/huaweicloud-obs/examples/custom_chain.rs
+++ b/services/huaweicloud-obs/examples/custom_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of building a custom credential chain with specific providers
-
-use async_trait::async_trait;
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
 use reqsign_http_send_reqwest::ReqwestHttpSend;
@@ -45,8 +43,6 @@ impl StaticCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
@@ -62,8 +58,6 @@ impl ProvideCredential for StaticCredentialProvider {
 /// Environment-based provider (simplified example)
 #[derive(Debug)]
 struct EnvCredentialProvider;
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/huaweicloud-obs/src/provide_credential/config.rs 
b/services/huaweicloud-obs/src/provide_credential/config.rs
index 03e8ec9..87704a0 100644
--- a/services/huaweicloud-obs/src/provide_credential/config.rs
+++ b/services/huaweicloud-obs/src/provide_credential/config.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Result;
 use reqsign_core::{Context, ProvideCredential};
 
@@ -42,8 +41,6 @@ impl ConfigCredentialProvider {
         Self
     }
 }
-
-#[async_trait]
 #[allow(deprecated)]
 impl ProvideCredential for ConfigCredentialProvider {
     type Credential = Credential;
diff --git a/services/huaweicloud-obs/src/provide_credential/default.rs 
b/services/huaweicloud-obs/src/provide_credential/default.rs
index f341041..07b2f6e 100644
--- a/services/huaweicloud-obs/src/provide_credential/default.rs
+++ b/services/huaweicloud-obs/src/provide_credential/default.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Result;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain};
 
@@ -122,8 +121,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/huaweicloud-obs/src/provide_credential/env.rs 
b/services/huaweicloud-obs/src/provide_credential/env.rs
index 8d4c555..a14f7e4 100644
--- a/services/huaweicloud-obs/src/provide_credential/env.rs
+++ b/services/huaweicloud-obs/src/provide_credential/env.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// EnvCredentialProvider loads Huawei Cloud credentials from environment 
variables.
@@ -34,8 +33,6 @@ impl EnvCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/huaweicloud-obs/src/provide_credential/static.rs 
b/services/huaweicloud-obs/src/provide_credential/static.rs
index 0c87671..0f75e57 100644
--- a/services/huaweicloud-obs/src/provide_credential/static.rs
+++ b/services/huaweicloud-obs/src/provide_credential/static.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// StaticCredentialProvider provides static credentials that are provided at 
initialization time.
@@ -52,8 +51,6 @@ impl StaticCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/huaweicloud-obs/src/sign_request.rs 
b/services/huaweicloud-obs/src/sign_request.rs
index 7aaa3e2..944f7f7 100644
--- a/services/huaweicloud-obs/src/sign_request.rs
+++ b/services/huaweicloud-obs/src/sign_request.rs
@@ -65,8 +65,6 @@ impl RequestSigner {
         self
     }
 }
-
-#[async_trait::async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
diff --git a/services/huaweicloud-obs/tests/credential_chain.rs 
b/services/huaweicloud-obs/tests/credential_chain.rs
index 14cd34d..5c8ccba 100644
--- a/services/huaweicloud-obs/tests/credential_chain.rs
+++ b/services/huaweicloud-obs/tests/credential_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Integration tests for ProvideCredentialChain with Huawei Cloud OBS
-
-use async_trait::async_trait;
 use reqsign_core::ProvideCredentialChain;
 use reqsign_core::{Context, OsEnv, ProvideCredential, Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -32,8 +30,6 @@ struct CountingProvider {
     return_credential: bool,
     call_count: Arc<std::sync::Mutex<usize>>,
 }
-
-#[async_trait]
 impl ProvideCredential for CountingProvider {
     type Credential = Credential;
 
@@ -191,8 +187,6 @@ async fn test_chain_with_security_token() {
 /// Mock provider that returns credentials with security token
 #[derive(Debug)]
 struct SecurityTokenProvider;
-
-#[async_trait]
 impl ProvideCredential for SecurityTokenProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/Cargo.toml b/services/oracle/Cargo.toml
index 4f53dc7..d1fa245 100644
--- a/services/oracle/Cargo.toml
+++ b/services/oracle/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 base64 = { workspace = true }
 http = { workspace = true }
 log = { workspace = true }
diff --git a/services/oracle/examples/oracle_chain_logging.rs 
b/services/oracle/examples/oracle_chain_logging.rs
index ea908a2..e361778 100644
--- a/services/oracle/examples/oracle_chain_logging.rs
+++ b/services/oracle/examples/oracle_chain_logging.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of using ProvideCredentialChain with logging to see credential 
resolution
-
-use async_trait::async_trait;
 use log::{debug, info};
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -41,8 +39,6 @@ impl<P> LoggingProvider<P> {
         }
     }
 }
-
-#[async_trait]
 impl<P> ProvideCredential for LoggingProvider<P>
 where
     P: ProvideCredential<Credential = Credential> + Send + Sync,
diff --git a/services/oracle/src/provide_credential/config.rs 
b/services/oracle/src/provide_credential/config.rs
index a801102..5cf4d97 100644
--- a/services/oracle/src/provide_credential/config.rs
+++ b/services/oracle/src/provide_credential/config.rs
@@ -18,7 +18,6 @@
 #![allow(deprecated)]
 
 use crate::{Config, Credential};
-use async_trait::async_trait;
 use log::debug;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
@@ -37,8 +36,6 @@ impl ConfigCredentialProvider {
         Self { config }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for ConfigCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/src/provide_credential/config_file.rs 
b/services/oracle/src/provide_credential/config_file.rs
index af9e903..41b7493 100644
--- a/services/oracle/src/provide_credential/config_file.rs
+++ b/services/oracle/src/provide_credential/config_file.rs
@@ -19,7 +19,6 @@ use crate::Credential;
 use crate::constants::{
     ORACLE_CONFIG_FILE, ORACLE_CONFIG_PATH, ORACLE_DEFAULT_PROFILE, 
ORACLE_PROFILE,
 };
-use async_trait::async_trait;
 use log::debug;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
@@ -40,8 +39,6 @@ impl ConfigFileCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for ConfigFileCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/src/provide_credential/default.rs 
b/services/oracle/src/provide_credential/default.rs
index e7265ad..5d88d34 100644
--- a/services/oracle/src/provide_credential/default.rs
+++ b/services/oracle/src/provide_credential/default.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::provide_credential::{ConfigFileCredentialProvider, 
EnvCredentialProvider};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 
 /// Default loader for Oracle Cloud Infrastructure.
@@ -141,8 +140,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/src/provide_credential/env.rs 
b/services/oracle/src/provide_credential/env.rs
index 8fb093c..50e3268 100644
--- a/services/oracle/src/provide_credential/env.rs
+++ b/services/oracle/src/provide_credential/env.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, ProvideCredential, Result};
 use std::time::Duration;
@@ -37,8 +36,6 @@ impl EnvCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/src/provide_credential/static_.rs 
b/services/oracle/src/provide_credential/static_.rs
index aa3338b..4f99d39 100644
--- a/services/oracle/src/provide_credential/static_.rs
+++ b/services/oracle/src/provide_credential/static_.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// StaticCredentialProvider provides static credentials that are provided at 
initialization time.
@@ -39,8 +38,6 @@ impl StaticCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/oracle/src/sign_request.rs 
b/services/oracle/src/sign_request.rs
index b7e6115..d4bc76d 100644
--- a/services/oracle/src/sign_request.rs
+++ b/services/oracle/src/sign_request.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use base64::{Engine as _, engine::general_purpose};
 use http::header::{AUTHORIZATION, DATE};
 use http::request::Parts;
@@ -49,8 +48,6 @@ impl Default for RequestSigner {
         Self::new()
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
diff --git a/services/oracle/tests/credential_chain.rs 
b/services/oracle/tests/credential_chain.rs
index 4e41fa9..cf1236e 100644
--- a/services/oracle/tests/credential_chain.rs
+++ b/services/oracle/tests/credential_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Integration tests for ProvideCredentialChain with Oracle Cloud 
Infrastructure
-
-use async_trait::async_trait;
 use reqsign_core::ProvideCredentialChain;
 use reqsign_core::{Context, OsEnv, ProvideCredential, Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -32,8 +30,6 @@ struct CountingProvider {
     return_credential: bool,
     call_count: Arc<std::sync::Mutex<usize>>,
 }
-
-#[async_trait]
 impl ProvideCredential for CountingProvider {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/Cargo.toml b/services/tencent-cos/Cargo.toml
index 4fd129b..2a9caf1 100644
--- a/services/tencent-cos/Cargo.toml
+++ b/services/tencent-cos/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 http = { workspace = true }
 log = { workspace = true }
 percent-encoding = { workspace = true }
diff --git a/services/tencent-cos/examples/tencent_chain_logging.rs 
b/services/tencent-cos/examples/tencent_chain_logging.rs
index 6d21797..86d01ef 100644
--- a/services/tencent-cos/examples/tencent_chain_logging.rs
+++ b/services/tencent-cos/examples/tencent_chain_logging.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Example of using ProvideCredentialChain with logging to see credential 
resolution
-
-use async_trait::async_trait;
 use log::{debug, info};
 use reqsign_core::{Context, OsEnv, ProvideCredential, ProvideCredentialChain, 
Result};
 use reqsign_file_read_tokio::TokioFileRead;
@@ -41,8 +39,6 @@ impl<P> LoggingProvider<P> {
         }
     }
 }
-
-#[async_trait]
 impl<P> ProvideCredential for LoggingProvider<P>
 where
     P: ProvideCredential<Credential = Credential> + Send + Sync,
diff --git 
a/services/tencent-cos/src/provide_credential/assume_role_with_web_identity.rs 
b/services/tencent-cos/src/provide_credential/assume_role_with_web_identity.rs
index 4805135..f89ad59 100644
--- 
a/services/tencent-cos/src/provide_credential/assume_role_with_web_identity.rs
+++ 
b/services/tencent-cos/src/provide_credential/assume_role_with_web_identity.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::constants::*;
-use async_trait::async_trait;
 use http::header::{AUTHORIZATION, CONTENT_LENGTH, CONTENT_TYPE};
 use log::debug;
 use reqsign_core::Result;
@@ -35,8 +34,6 @@ impl AssumeRoleWithWebIdentityCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for AssumeRoleWithWebIdentityCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/src/provide_credential/config.rs 
b/services/tencent-cos/src/provide_credential/config.rs
index c075ada..754e858 100644
--- a/services/tencent-cos/src/provide_credential/config.rs
+++ b/services/tencent-cos/src/provide_credential/config.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Result;
 use reqsign_core::{Context, ProvideCredential};
 
@@ -42,8 +41,6 @@ impl ConfigCredentialProvider {
         Self
     }
 }
-
-#[async_trait]
 #[allow(deprecated)]
 impl ProvideCredential for ConfigCredentialProvider {
     type Credential = Credential;
diff --git a/services/tencent-cos/src/provide_credential/default.rs 
b/services/tencent-cos/src/provide_credential/default.rs
index fd7e72f..96af581 100644
--- a/services/tencent-cos/src/provide_credential/default.rs
+++ b/services/tencent-cos/src/provide_credential/default.rs
@@ -19,7 +19,6 @@ use crate::Credential;
 use crate::provide_credential::{
     AssumeRoleWithWebIdentityCredentialProvider, EnvCredentialProvider,
 };
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain, Result};
 
 /// Default loader for Tencent COS.
@@ -152,8 +151,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/src/provide_credential/env.rs 
b/services/tencent-cos/src/provide_credential/env.rs
index de129dd..97f3e29 100644
--- a/services/tencent-cos/src/provide_credential/env.rs
+++ b/services/tencent-cos/src/provide_credential/env.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::{Credential, constants::*};
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// EnvCredentialProvider loads Tencent Cloud credentials from environment 
variables.
@@ -34,8 +33,6 @@ impl EnvCredentialProvider {
         Self {}
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/src/provide_credential/static.rs 
b/services/tencent-cos/src/provide_credential/static.rs
index 0d37991..91d6363 100644
--- a/services/tencent-cos/src/provide_credential/static.rs
+++ b/services/tencent-cos/src/provide_credential/static.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 use crate::Credential;
-use async_trait::async_trait;
 use reqsign_core::{Context, ProvideCredential, Result};
 
 /// StaticCredentialProvider provides static credentials that are provided at 
initialization time.
@@ -50,8 +49,6 @@ impl StaticCredentialProvider {
         }
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/src/sign_request.rs 
b/services/tencent-cos/src/sign_request.rs
index bae88d7..8e1384a 100644
--- a/services/tencent-cos/src/sign_request.rs
+++ b/services/tencent-cos/src/sign_request.rs
@@ -17,7 +17,6 @@
 
 use crate::Credential;
 use crate::constants::TENCENT_URI_ENCODE_SET;
-use async_trait::async_trait;
 use http::header::{AUTHORIZATION, DATE};
 use http::request::Parts;
 use log::debug;
@@ -53,8 +52,6 @@ impl RequestSigner {
         self
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 
diff --git a/services/tencent-cos/tests/credential_chain.rs 
b/services/tencent-cos/tests/credential_chain.rs
index 9fdcd3c..210eaf9 100644
--- a/services/tencent-cos/tests/credential_chain.rs
+++ b/services/tencent-cos/tests/credential_chain.rs
@@ -16,8 +16,6 @@
 // under the License.
 
 //! Integration tests for ProvideCredentialChain with Tencent COS
-
-use async_trait::async_trait;
 use reqsign_core::ProvideCredentialChain;
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, OsEnv, ProvideCredential, Result};
@@ -34,8 +32,6 @@ struct CountingProvider {
     return_credential: bool,
     call_count: Arc<std::sync::Mutex<usize>>,
 }
-
-#[async_trait]
 impl ProvideCredential for CountingProvider {
     type Credential = Credential;
 
@@ -191,8 +187,6 @@ async fn test_chain_with_security_token() {
 /// Mock provider that returns credentials with security token
 #[derive(Debug)]
 struct SecurityTokenProvider;
-
-#[async_trait]
 impl ProvideCredential for SecurityTokenProvider {
     type Credential = Credential;
 
diff --git a/services/volcengine-tos/Cargo.toml 
b/services/volcengine-tos/Cargo.toml
index e24c8b4..ef43b92 100644
--- a/services/volcengine-tos/Cargo.toml
+++ b/services/volcengine-tos/Cargo.toml
@@ -28,7 +28,6 @@ rust-version.workspace = true
 
 [dependencies]
 anyhow = { workspace = true }
-async-trait = { workspace = true }
 http = { workspace = true }
 log = { workspace = true }
 percent-encoding = { workspace = true }
diff --git a/services/volcengine-tos/src/provide_credential/default.rs 
b/services/volcengine-tos/src/provide_credential/default.rs
index 678596b..63cca8e 100644
--- a/services/volcengine-tos/src/provide_credential/default.rs
+++ b/services/volcengine-tos/src/provide_credential/default.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Result;
 use reqsign_core::{Context, ProvideCredential, ProvideCredentialChain};
 
@@ -122,8 +121,6 @@ impl DefaultCredentialProviderBuilder {
         DefaultCredentialProvider::with_chain(chain)
     }
 }
-
-#[async_trait]
 impl ProvideCredential for DefaultCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/volcengine-tos/src/provide_credential/env.rs 
b/services/volcengine-tos/src/provide_credential/env.rs
index 5c68b3e..fe673bf 100644
--- a/services/volcengine-tos/src/provide_credential/env.rs
+++ b/services/volcengine-tos/src/provide_credential/env.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Context;
 use reqsign_core::ProvideCredential;
 use reqsign_core::Result;
@@ -38,8 +37,6 @@ impl EnvCredentialProvider {
         Self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for EnvCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/volcengine-tos/src/provide_credential/static.rs 
b/services/volcengine-tos/src/provide_credential/static.rs
index 42f4df7..ab4c4d7 100644
--- a/services/volcengine-tos/src/provide_credential/static.rs
+++ b/services/volcengine-tos/src/provide_credential/static.rs
@@ -15,7 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use async_trait::async_trait;
 use reqsign_core::Context;
 use reqsign_core::ProvideCredential;
 use reqsign_core::Result;
@@ -49,8 +48,6 @@ impl StaticCredentialProvider {
         self
     }
 }
-
-#[async_trait]
 impl ProvideCredential for StaticCredentialProvider {
     type Credential = Credential;
 
diff --git a/services/volcengine-tos/src/sign_request.rs 
b/services/volcengine-tos/src/sign_request.rs
index c4e1c42..6196d8a 100644
--- a/services/volcengine-tos/src/sign_request.rs
+++ b/services/volcengine-tos/src/sign_request.rs
@@ -15,10 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use std::fmt::Write;
-use std::sync::LazyLock;
-
-use async_trait::async_trait;
 use http::header::AUTHORIZATION;
 use http::{HeaderName, HeaderValue, header};
 use log::debug;
@@ -26,6 +22,8 @@ use percent_encoding::percent_decode_str;
 use reqsign_core::hash::{hex_hmac_sha256, hex_sha256, hmac_sha256};
 use reqsign_core::time::Timestamp;
 use reqsign_core::{Context, Result, SignRequest, SigningRequest};
+use std::fmt::Write;
+use std::sync::LazyLock;
 
 use crate::constants::*;
 use crate::credential::Credential;
@@ -66,8 +64,6 @@ impl RequestSigner {
         self
     }
 }
-
-#[async_trait]
 impl SignRequest for RequestSigner {
     type Credential = Credential;
 


Reply via email to