Issue:
Bug: [REFACTOR] introducing `hyperswitch_interface` crates



Create a new crate `Hyperswitch-interface` containing below modules for now: 
`secrets_interface`: Module used for application config `encryption` and `decryption` during startup which will contain its own trait and error types
`encryption_interface`: Module used for user value `encryption` and `decryption` during runtime which will contain its own trait and error types

Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Create a new crate `Hyperswitch-interface` containing below modules for now: 
`secrets_interface`: Module used for application config `encryption` and `decryption` during startup which will contain its own trait and error types
`encryption_interface`: Module used for user value `encryption` and `decryption` during runtime which will contain its own trait and error types

This PR only adds the above crate with the addition of `secret_management_config` and `encryption_management_config` in the `router`

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
New crates addition which doesn't integrate with other existing crates yet. So basic sanity testing should suffice

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable


Testing:

New crates addition which doesn't integrate with other existing crates yet. So basic sanity testing should suffice

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 49ccfc2c645..4bee1804f4c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2495,6 +2495,7 @@ dependencies = [
  "hex",
  "hyper",
  "hyper-proxy",
+ "hyperswitch_interfaces",
  "masking",
  "once_cell",
  "router_env",
@@ -3214,6 +3215,18 @@ dependencies = [
  "tokio-native-tls",
 ]
 
+[[package]]
+name = "hyperswitch_interfaces"
+version = "0.1.0"
+dependencies = [
+ "async-trait",
+ "common_utils",
+ "dyn-clone",
+ "masking",
+ "serde",
+ "thiserror",
+]
+
 [[package]]
 name = "iana-time-zone"
 version = "0.1.58"
@@ -5186,6 +5199,7 @@ dependencies = [
  "hex",
  "http",
  "hyper",
+ "hyperswitch_interfaces",
  "image",
  "infer 0.13.0",
  "josekit",
diff --git a/crates/drainer/src/connection.rs b/crates/drainer/src/connection.rs
index 788ff1456e2..e01b72150c5 100644
--- a/crates/drainer/src/connection.rs
+++ b/crates/drainer/src/connection.rs
@@ -3,7 +3,10 @@ use diesel::PgConnection;
 #[cfg(feature = "aws_kms")]
 use external_services::aws_kms::{self, decrypt::AwsKmsDecrypt};
 #[cfg(feature = "hashicorp-vault")]
-use external_services::hashicorp_vault::{self, decrypt::VaultFetch, Kv2};
+use external_services::hashicorp_vault::{
+    core::{HashiCorpVault, Kv2},
+    decrypt::VaultFetch,
+};
 #[cfg(not(feature = "aws_kms"))]
 use masking::PeekInterface;
 
@@ -28,8 +31,8 @@ pub async fn redis_connection(
 pub async fn diesel_make_pg_pool(
     database: &Database,
     _test_transaction: bool,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &'static aws_kms::AwsKmsClient,
-    #[cfg(feature = "hashicorp-vault")] hashicorp_client: &'static hashicorp_vault::HashiCorpVault,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &'static aws_kms::core::AwsKmsClient,
+    #[cfg(feature = "hashicorp-vault")] hashicorp_client: &'static HashiCorpVault,
 ) -> PgPool {
     let password = database.password.clone();
     #[cfg(feature = "hashicorp-vault")]
diff --git a/crates/drainer/src/services.rs b/crates/drainer/src/services.rs
index e6ca8d023a0..3918c756c10 100644
--- a/crates/drainer/src/services.rs
+++ b/crates/drainer/src/services.rs
@@ -34,10 +34,10 @@ impl Store {
                 &config.master_database,
                 test_transaction,
                 #[cfg(feature = "aws_kms")]
-                external_services::aws_kms::get_aws_kms_client(&config.kms).await,
+                external_services::aws_kms::core::get_aws_kms_client(&config.kms).await,
                 #[cfg(feature = "hashicorp-vault")]
                 #[allow(clippy::expect_used)]
-                external_services::hashicorp_vault::get_hashicorp_client(&config.hc_vault)
+                external_services::hashicorp_vault::core::get_hashicorp_client(&config.hc_vault)
                     .await
                     .expect("Failed while getting hashicorp client"),
             )
diff --git a/crates/drainer/src/settings.rs b/crates/drainer/src/settings.rs
index 17b0b68b324..de5af654540 100644
--- a/crates/drainer/src/settings.rs
+++ b/crates/drainer/src/settings.rs
@@ -14,7 +14,7 @@ use serde::Deserialize;
 use crate::errors;
 
 #[cfg(feature = "aws_kms")]
-pub type Password = aws_kms::AwsKmsValue;
+pub type Password = aws_kms::core::AwsKmsValue;
 #[cfg(not(feature = "aws_kms"))]
 pub type Password = masking::Secret<String>;
 
@@ -36,9 +36,9 @@ pub struct Settings {
     pub log: Log,
     pub drainer: DrainerSettings,
     #[cfg(feature = "aws_kms")]
-    pub kms: aws_kms::AwsKmsConfig,
+    pub kms: aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    pub hc_vault: hashicorp_vault::HashiCorpVaultConfig,
+    pub hc_vault: hashicorp_vault::core::HashiCorpVaultConfig,
 }
 
 #[derive(Debug, Deserialize, Clone)]
diff --git a/crates/external_services/Cargo.toml b/crates/external_services/Cargo.toml
index 2b6bc22b2e9..58c81946017 100644
--- a/crates/external_services/Cargo.toml
+++ b/crates/external_services/Cargo.toml
@@ -35,5 +35,6 @@ hex = "0.4.3"
 
 # First party crates
 common_utils = { version = "0.1.0", path = "../common_utils" }
+hyperswitch_interfaces = { version = "0.1.0", path = "../hyperswitch_interfaces" }
 masking = { version = "0.1.0", path = "../masking" }
 router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
diff --git a/crates/external_services/src/aws_kms.rs b/crates/external_services/src/aws_kms.rs
index cf21f36f22b..3e5353fd9e3 100644
--- a/crates/external_services/src/aws_kms.rs
+++ b/crates/external_services/src/aws_kms.rs
@@ -1,284 +1,7 @@
 //! Interactions with the AWS KMS SDK
 
-use std::time::Instant;
+pub mod core;
 
-use aws_config::meta::region::RegionProviderChain;
-use aws_sdk_kms::{config::Region, primitives::Blob, Client};
-use base64::Engine;
-use common_utils::errors::CustomResult;
-use error_stack::{IntoReport, ResultExt};
-use masking::{PeekInterface, Secret};
-use router_env::logger;
-/// decrypting data using the AWS KMS SDK.
 pub mod decrypt;
 
-use crate::{consts, metrics};
-
-static AWS_KMS_CLIENT: tokio::sync::OnceCell<AwsKmsClient> = tokio::sync::OnceCell::const_new();
-
-/// Returns a shared AWS KMS client, or initializes a new one if not previously initialized.
-#[inline]
-pub async fn get_aws_kms_client(config: &AwsKmsConfig) -> &'static AwsKmsClient {
-    AWS_KMS_CLIENT
-        .get_or_init(|| AwsKmsClient::new(config))
-        .await
-}
-
-/// Configuration parameters required for constructing a [`AwsKmsClient`].
-#[derive(Clone, Debug, Default, serde::Deserialize)]
-#[serde(default)]
-pub struct AwsKmsConfig {
-    /// The AWS key identifier of the KMS key used to encrypt or decrypt data.
-    pub key_id: String,
-
-    /// The AWS region to send KMS requests to.
-    pub region: String,
-}
-
-/// Client for AWS KMS operations.
-#[derive(Debug)]
-pub struct AwsKmsClient {
-    inner_client: Client,
-    key_id: String,
-}
-
-impl AwsKmsClient {
-    /// Constructs a new AWS KMS client.
-    pub async fn new(config: &AwsKmsConfig) -> Self {
-        let region_provider = RegionProviderChain::first_try(Region::new(config.region.clone()));
-        let sdk_config = aws_config::from_env().region(region_provider).load().await;
-
-        Self {
-            inner_client: Client::new(&sdk_config),
-            key_id: config.key_id.clone(),
-        }
-    }
-
-    /// Decrypts the provided base64-encoded encrypted data using the AWS KMS SDK. We assume that
-    /// the SDK has the values required to interact with the AWS KMS APIs (`AWS_ACCESS_KEY_ID` and
-    /// `AWS_SECRET_ACCESS_KEY`) either set in environment variables, or that the SDK is running in
-    /// a machine that is able to assume an IAM role.
-    pub async fn decrypt(&self, data: impl AsRef<[u8]>) -> CustomResult<String, AwsKmsError> {
-        let start = Instant::now();
-        let data = consts::BASE64_ENGINE
-            .decode(data)
-            .into_report()
-            .change_context(AwsKmsError::Base64DecodingFailed)?;
-        let ciphertext_blob = Blob::new(data);
-
-        let decrypt_output = self
-            .inner_client
-            .decrypt()
-            .key_id(&self.key_id)
-            .ciphertext_blob(ciphertext_blob)
-            .send()
-            .await
-            .map_err(|error| {
-                // Logging using `Debug` representation of the error as the `Display`
-                // representation does not hold sufficient information.
-                logger::error!(aws_kms_sdk_error=?error, "Failed to AWS KMS decrypt data");
-                metrics::AWS_KMS_DECRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]);
-                error
-            })
-            .into_report()
-            .change_context(AwsKmsError::DecryptionFailed)?;
-
-        let output = decrypt_output
-            .plaintext
-            .ok_or(AwsKmsError::MissingPlaintextDecryptionOutput)
-            .into_report()
-            .and_then(|blob| {
-                String::from_utf8(blob.into_inner())
-                    .into_report()
-                    .change_context(AwsKmsError::Utf8DecodingFailed)
-            })?;
-
-        let time_taken = start.elapsed();
-        metrics::AWS_KMS_DECRYPT_TIME.record(&metrics::CONTEXT, time_taken.as_secs_f64(), &[]);
-
-        Ok(output)
-    }
-
-    /// Encrypts the provided String data using the AWS KMS SDK. We assume that
-    /// the SDK has the values required to interact with the AWS KMS APIs (`AWS_ACCESS_KEY_ID` and
-    /// `AWS_SECRET_ACCESS_KEY`) either set in environment variables, or that the SDK is running in
-    /// a machine that is able to assume an IAM role.
-    pub async fn encrypt(&self, data: impl AsRef<[u8]>) -> CustomResult<String, AwsKmsError> {
-        let start = Instant::now();
-        let plaintext_blob = Blob::new(data.as_ref());
-
-        let encrypted_output = self
-            .inner_client
-            .encrypt()
-            .key_id(&self.key_id)
-            .plaintext(plaintext_blob)
-            .send()
-            .await
-            .map_err(|error| {
-                // Logging using `Debug` representation of the error as the `Display`
-                // representation does not hold sufficient information.
-                logger::error!(aws_kms_sdk_error=?error, "Failed to AWS KMS encrypt data");
-                metrics::AWS_KMS_ENCRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]);
-                error
-            })
-            .into_report()
-            .change_context(AwsKmsError::EncryptionFailed)?;
-
-        let output = encrypted_output
-            .ciphertext_blob
-            .ok_or(AwsKmsError::MissingCiphertextEncryptionOutput)
-            .into_report()
-            .map(|blob| consts::BASE64_ENGINE.encode(blob.into_inner()))?;
-        let time_taken = start.elapsed();
-        metrics::AWS_KMS_ENCRYPT_TIME.record(&metrics::CONTEXT, time_taken.as_secs_f64(), &[]);
-
-        Ok(output)
-    }
-}
-
-/// Errors that could occur during AWS KMS operations.
-#[derive(Debug, thiserror::Error)]
-pub enum AwsKmsError {
-    /// An error occurred when base64 encoding input data.
-    #[error("Failed to base64 encode input data")]
-    Base64EncodingFailed,
-
-    /// An error occurred when base64 decoding input data.
-    #[error("Failed to base64 decode input data")]
-    Base64DecodingFailed,
-
-    /// An error occurred when AWS KMS decrypting input data.
-    #[error("Failed to AWS KMS decrypt input data")]
-    DecryptionFailed,
-
-    /// An error occurred when AWS KMS encrypting input data.
-    #[error("Failed to AWS KMS encrypt input data")]
-    EncryptionFailed,
-
-    /// The AWS KMS decrypted output does not include a plaintext output.
-    #[error("Missing plaintext AWS KMS decryption output")]
-    MissingPlaintextDecryptionOutput,
-
-    /// The AWS KMS encrypted output does not include a ciphertext output.
-    #[error("Missing ciphertext AWS KMS encryption output")]
-    MissingCiphertextEncryptionOutput,
-
-    /// An error occurred UTF-8 decoding AWS KMS decrypted output.
-    #[error("Failed to UTF-8 decode decryption output")]
-    Utf8DecodingFailed,
-
-    /// The AWS KMS client has not been initialized.
-    #[error("The AWS KMS client has not been initialized")]
-    AwsKmsClientNotInitialized,
-}
-
-impl AwsKmsConfig {
-    /// Verifies that the [`AwsKmsClient`] configuration is usable.
-    pub fn validate(&self) -> Result<(), &'static str> {
-        use common_utils::{ext_traits::ConfigExt, fp_utils::when};
-
-        when(self.key_id.is_default_or_empty(), || {
-            Err("KMS AWS key ID must not be empty")
-        })?;
-
-        when(self.region.is_default_or_empty(), || {
-            Err("KMS AWS region must not be empty")
-        })
-    }
-}
-
-/// A wrapper around a AWS KMS value that can be decrypted.
-#[derive(Clone, Debug, Default, serde::Deserialize, Eq, PartialEq)]
-#[serde(transparent)]
-pub struct AwsKmsValue(Secret<String>);
-
-impl common_utils::ext_traits::ConfigExt for AwsKmsValue {
-    fn is_empty_after_trim(&self) -> bool {
-        self.0.peek().is_empty_after_trim()
-    }
-}
-
-impl From<String> for AwsKmsValue {
-    fn from(value: String) -> Self {
-        Self(Secret::new(value))
-    }
-}
-
-impl From<Secret<String>> for AwsKmsValue {
-    fn from(value: Secret<String>) -> Self {
-        Self(value)
-    }
-}
-
-#[cfg(feature = "hashicorp-vault")]
-#[async_trait::async_trait]
-impl super::hashicorp_vault::decrypt::VaultFetch for AwsKmsValue {
-    async fn fetch_inner<En>(
-        self,
-        client: &super::hashicorp_vault::HashiCorpVault,
-    ) -> error_stack::Result<Self, super::hashicorp_vault::HashiCorpError>
-    where
-        for<'a> En: super::hashicorp_vault::Engine<
-                ReturnType<'a, String> = std::pin::Pin<
-                    Box<
-                        dyn std::future::Future<
-                                Output = error_stack::Result<
-                                    String,
-                                    super::hashicorp_vault::HashiCorpError,
-                                >,
-                            > + Send
-                            + 'a,
-                    >,
-                >,
-            > + 'a,
-    {
-        self.0.fetch_inner::<En>(client).await.map(AwsKmsValue)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    #![allow(clippy::expect_used)]
-    #[tokio::test]
-    async fn check_aws_kms_encryption() {
-        std::env::set_var("AWS_SECRET_ACCESS_KEY", "YOUR SECRET ACCESS KEY");
-        std::env::set_var("AWS_ACCESS_KEY_ID", "YOUR AWS ACCESS KEY ID");
-        use super::*;
-        let config = AwsKmsConfig {
-            key_id: "YOUR AWS KMS KEY ID".to_string(),
-            region: "AWS REGION".to_string(),
-        };
-
-        let data = "hello".to_string();
-        let binding = data.as_bytes();
-        let kms_encrypted_fingerprint = AwsKmsClient::new(&config)
-            .await
-            .encrypt(binding)
-            .await
-            .expect("aws kms encryption failed");
-
-        println!("{}", kms_encrypted_fingerprint);
-    }
-
-    #[tokio::test]
-    async fn check_aws_kms_decrypt() {
-        std::env::set_var("AWS_SECRET_ACCESS_KEY", "YOUR SECRET ACCESS KEY");
-        std::env::set_var("AWS_ACCESS_KEY_ID", "YOUR AWS ACCESS KEY ID");
-        use super::*;
-        let config = AwsKmsConfig {
-            key_id: "YOUR AWS KMS KEY ID".to_string(),
-            region: "AWS REGION".to_string(),
-        };
-
-        // Should decrypt to hello
-        let data = "AWS KMS ENCRYPTED CIPHER".to_string();
-        let binding = data.as_bytes();
-        let kms_encrypted_fingerprint = AwsKmsClient::new(&config)
-            .await
-            .decrypt(binding)
-            .await
-            .expect("aws kms decryption failed");
-
-        println!("{}", kms_encrypted_fingerprint);
-    }
-}
+pub mod implementers;
diff --git a/crates/external_services/src/aws_kms/core.rs b/crates/external_services/src/aws_kms/core.rs
new file mode 100644
index 00000000000..c01bcbfb094
--- /dev/null
+++ b/crates/external_services/src/aws_kms/core.rs
@@ -0,0 +1,299 @@
+//! Interactions with the AWS KMS SDK
+
+use std::time::Instant;
+
+use aws_config::meta::region::RegionProviderChain;
+use aws_sdk_kms::{config::Region, primitives::Blob, Client};
+use base64::Engine;
+use common_utils::errors::CustomResult;
+use error_stack::{IntoReport, ResultExt};
+use masking::{PeekInterface, Secret};
+use router_env::logger;
+
+#[cfg(feature = "hashicorp-vault")]
+use crate::hashicorp_vault;
+use crate::{aws_kms::decrypt::AwsKmsDecrypt, consts, metrics};
+
+pub(crate) static AWS_KMS_CLIENT: tokio::sync::OnceCell<AwsKmsClient> =
+    tokio::sync::OnceCell::const_new();
+
+/// Returns a shared AWS KMS client, or initializes a new one if not previously initialized.
+#[inline]
+pub async fn get_aws_kms_client(config: &AwsKmsConfig) -> &'static AwsKmsClient {
+    AWS_KMS_CLIENT
+        .get_or_init(|| AwsKmsClient::new(config))
+        .await
+}
+
+/// Configuration parameters required for constructing a [`AwsKmsClient`].
+#[derive(Clone, Debug, Default, serde::Deserialize)]
+#[serde(default)]
+pub struct AwsKmsConfig {
+    /// The AWS key identifier of the KMS key used to encrypt or decrypt data.
+    pub key_id: String,
+
+    /// The AWS region to send KMS requests to.
+    pub region: String,
+}
+
+/// Client for AWS KMS operations.
+#[derive(Debug, Clone)]
+pub struct AwsKmsClient {
+    inner_client: Client,
+    key_id: String,
+}
+
+impl AwsKmsClient {
+    /// Constructs a new AWS KMS client.
+    pub async fn new(config: &AwsKmsConfig) -> Self {
+        let region_provider = RegionProviderChain::first_try(Region::new(config.region.clone()));
+        let sdk_config = aws_config::from_env().region(region_provider).load().await;
+
+        Self {
+            inner_client: Client::new(&sdk_config),
+            key_id: config.key_id.clone(),
+        }
+    }
+
+    /// Decrypts the provided base64-encoded encrypted data using the AWS KMS SDK. We assume that
+    /// the SDK has the values required to interact with the AWS KMS APIs (`AWS_ACCESS_KEY_ID` and
+    /// `AWS_SECRET_ACCESS_KEY`) either set in environment variables, or that the SDK is running in
+    /// a machine that is able to assume an IAM role.
+    pub async fn decrypt(&self, data: impl AsRef<[u8]>) -> CustomResult<String, AwsKmsError> {
+        let start = Instant::now();
+        let data = consts::BASE64_ENGINE
+            .decode(data)
+            .into_report()
+            .change_context(AwsKmsError::Base64DecodingFailed)?;
+        let ciphertext_blob = Blob::new(data);
+
+        let decrypt_output = self
+            .inner_client
+            .decrypt()
+            .key_id(&self.key_id)
+            .ciphertext_blob(ciphertext_blob)
+            .send()
+            .await
+            .map_err(|error| {
+                // Logging using `Debug` representation of the error as the `Display`
+                // representation does not hold sufficient information.
+                logger::error!(aws_kms_sdk_error=?error, "Failed to AWS KMS decrypt data");
+                metrics::AWS_KMS_DECRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                error
+            })
+            .into_report()
+            .change_context(AwsKmsError::DecryptionFailed)?;
+
+        let output = decrypt_output
+            .plaintext
+            .ok_or(AwsKmsError::MissingPlaintextDecryptionOutput)
+            .into_report()
+            .and_then(|blob| {
+                String::from_utf8(blob.into_inner())
+                    .into_report()
+                    .change_context(AwsKmsError::Utf8DecodingFailed)
+            })?;
+
+        let time_taken = start.elapsed();
+        metrics::AWS_KMS_DECRYPT_TIME.record(&metrics::CONTEXT, time_taken.as_secs_f64(), &[]);
+
+        Ok(output)
+    }
+
+    /// Encrypts the provided String data using the AWS KMS SDK. We assume that
+    /// the SDK has the values required to interact with the AWS KMS APIs (`AWS_ACCESS_KEY_ID` and
+    /// `AWS_SECRET_ACCESS_KEY`) either set in environment variables, or that the SDK is running in
+    /// a machine that is able to assume an IAM role.
+    pub async fn encrypt(&self, data: impl AsRef<[u8]>) -> CustomResult<String, AwsKmsError> {
+        let start = Instant::now();
+        let plaintext_blob = Blob::new(data.as_ref());
+
+        let encrypted_output = self
+            .inner_client
+            .encrypt()
+            .key_id(&self.key_id)
+            .plaintext(plaintext_blob)
+            .send()
+            .await
+            .map_err(|error| {
+                // Logging using `Debug` representation of the error as the `Display`
+                // representation does not hold sufficient information.
+                logger::error!(aws_kms_sdk_error=?error, "Failed to AWS KMS encrypt data");
+                metrics::AWS_KMS_ENCRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]);
+                error
+            })
+            .into_report()
+            .change_context(AwsKmsError::EncryptionFailed)?;
+
+        let output = encrypted_output
+            .ciphertext_blob
+            .ok_or(AwsKmsError::MissingCiphertextEncryptionOutput)
+            .into_report()
+            .map(|blob| consts::BASE64_ENGINE.encode(blob.into_inner()))?;
+        let time_taken = start.elapsed();
+        metrics::AWS_KMS_ENCRYPT_TIME.record(&metrics::CONTEXT, time_taken.as_secs_f64(), &[]);
+
+        Ok(output)
+    }
+}
+
+/// Errors that could occur during KMS operations.
+#[derive(Debug, thiserror::Error)]
+pub enum AwsKmsError {
+    /// An error occurred when base64 encoding input data.
+    #[error("Failed to base64 encode input data")]
+    Base64EncodingFailed,
+
+    /// An error occurred when base64 decoding input data.
+    #[error("Failed to base64 decode input data")]
+    Base64DecodingFailed,
+
+    /// An error occurred when AWS KMS decrypting input data.
+    #[error("Failed to AWS KMS decrypt input data")]
+    DecryptionFailed,
+
+    /// An error occurred when AWS KMS encrypting input data.
+    #[error("Failed to AWS KMS encrypt input data")]
+    EncryptionFailed,
+
+    /// The AWS KMS decrypted output does not include a plaintext output.
+    #[error("Missing plaintext AWS KMS decryption output")]
+    MissingPlaintextDecryptionOutput,
+
+    /// The AWS KMS encrypted output does not include a ciphertext output.
+    #[error("Missing ciphertext AWS KMS encryption output")]
+    MissingCiphertextEncryptionOutput,
+
+    /// An error occurred UTF-8 decoding AWS KMS decrypted output.
+    #[error("Failed to UTF-8 decode decryption output")]
+    Utf8DecodingFailed,
+
+    /// The AWS KMS client has not been initialized.
+    #[error("The AWS KMS client has not been initialized")]
+    AwsKmsClientNotInitialized,
+}
+
+impl AwsKmsConfig {
+    /// Verifies that the [`AwsKmsClient`] configuration is usable.
+    pub fn validate(&self) -> Result<(), &'static str> {
+        use common_utils::{ext_traits::ConfigExt, fp_utils::when};
+
+        when(self.key_id.is_default_or_empty(), || {
+            Err("KMS AWS key ID must not be empty")
+        })?;
+
+        when(self.region.is_default_or_empty(), || {
+            Err("KMS AWS region must not be empty")
+        })
+    }
+}
+
+/// A wrapper around a AWS KMS value that can be decrypted.
+#[derive(Clone, Debug, Default, serde::Deserialize, Eq, PartialEq)]
+#[serde(transparent)]
+pub struct AwsKmsValue(Secret<String>);
+
+impl common_utils::ext_traits::ConfigExt for AwsKmsValue {
+    fn is_empty_after_trim(&self) -> bool {
+        self.0.peek().is_empty_after_trim()
+    }
+}
+
+impl From<String> for AwsKmsValue {
+    fn from(value: String) -> Self {
+        Self(Secret::new(value))
+    }
+}
+
+impl From<Secret<String>> for AwsKmsValue {
+    fn from(value: Secret<String>) -> Self {
+        Self(value)
+    }
+}
+
+#[cfg(feature = "hashicorp-vault")]
+#[async_trait::async_trait]
+impl hashicorp_vault::decrypt::VaultFetch for AwsKmsValue {
+    async fn fetch_inner<En>(
+        self,
+        client: &hashicorp_vault::core::HashiCorpVault,
+    ) -> error_stack::Result<Self, hashicorp_vault::core::HashiCorpError>
+    where
+        for<'a> En: hashicorp_vault::core::Engine<
+                ReturnType<'a, String> = std::pin::Pin<
+                    Box<
+                        dyn std::future::Future<
+                                Output = error_stack::Result<
+                                    String,
+                                    hashicorp_vault::core::HashiCorpError,
+                                >,
+                            > + Send
+                            + 'a,
+                    >,
+                >,
+            > + 'a,
+    {
+        self.0.fetch_inner::<En>(client).await.map(AwsKmsValue)
+    }
+}
+
+#[async_trait::async_trait]
+impl AwsKmsDecrypt for &AwsKmsValue {
+    type Output = String;
+    async fn decrypt_inner(
+        self,
+        aws_kms_client: &AwsKmsClient,
+    ) -> CustomResult<Self::Output, AwsKmsError> {
+        aws_kms_client
+            .decrypt(self.0.peek())
+            .await
+            .attach_printable("Failed to decrypt AWS KMS value")
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #![allow(clippy::expect_used)]
+    #[tokio::test]
+    async fn check_aws_kms_encryption() {
+        std::env::set_var("AWS_SECRET_ACCESS_KEY", "YOUR SECRET ACCESS KEY");
+        std::env::set_var("AWS_ACCESS_KEY_ID", "YOUR AWS ACCESS KEY ID");
+        use super::*;
+        let config = AwsKmsConfig {
+            key_id: "YOUR AWS KMS KEY ID".to_string(),
+            region: "AWS REGION".to_string(),
+        };
+
+        let data = "hello".to_string();
+        let binding = data.as_bytes();
+        let kms_encrypted_fingerprint = AwsKmsClient::new(&config)
+            .await
+            .encrypt(binding)
+            .await
+            .expect("aws kms encryption failed");
+
+        println!("{}", kms_encrypted_fingerprint);
+    }
+
+    #[tokio::test]
+    async fn check_aws_kms_decrypt() {
+        std::env::set_var("AWS_SECRET_ACCESS_KEY", "YOUR SECRET ACCESS KEY");
+        std::env::set_var("AWS_ACCESS_KEY_ID", "YOUR AWS ACCESS KEY ID");
+        use super::*;
+        let config = AwsKmsConfig {
+            key_id: "YOUR AWS KMS KEY ID".to_string(),
+            region: "AWS REGION".to_string(),
+        };
+
+        // Should decrypt to hello
+        let data = "AWS KMS ENCRYPTED CIPHER".to_string();
+        let binding = data.as_bytes();
+        let kms_encrypted_fingerprint = AwsKmsClient::new(&config)
+            .await
+            .decrypt(binding)
+            .await
+            .expect("aws kms decryption failed");
+
+        println!("{}", kms_encrypted_fingerprint);
+    }
+}
diff --git a/crates/external_services/src/aws_kms/decrypt.rs b/crates/external_services/src/aws_kms/decrypt.rs
index 9abd4fefbef..47edb8f958f 100644
--- a/crates/external_services/src/aws_kms/decrypt.rs
+++ b/crates/external_services/src/aws_kms/decrypt.rs
@@ -1,6 +1,7 @@
+//! Decrypting data using the AWS KMS SDK.
 use common_utils::errors::CustomResult;
 
-use super::*;
+use crate::aws_kms::core::{AwsKmsClient, AwsKmsError, AWS_KMS_CLIENT};
 
 #[async_trait::async_trait]
 /// This trait performs in place decryption of the structure on which this is implemented
@@ -26,17 +27,3 @@ pub trait AwsKmsDecrypt {
         self.decrypt_inner(client).await
     }
 }
-
-#[async_trait::async_trait]
-impl AwsKmsDecrypt for &AwsKmsValue {
-    type Output = String;
-    async fn decrypt_inner(
-        self,
-        aws_kms_client: &AwsKmsClient,
-    ) -> CustomResult<Self::Output, AwsKmsError> {
-        aws_kms_client
-            .decrypt(self.0.peek())
-            .await
-            .attach_printable("Failed to decrypt AWS KMS value")
-    }
-}
diff --git a/crates/external_services/src/aws_kms/implementers.rs b/crates/external_services/src/aws_kms/implementers.rs
new file mode 100644
index 00000000000..cc00dbf3468
--- /dev/null
+++ b/crates/external_services/src/aws_kms/implementers.rs
@@ -0,0 +1,41 @@
+//! Trait implementations for aws kms client
+
+use common_utils::errors::CustomResult;
+use error_stack::ResultExt;
+use hyperswitch_interfaces::{
+    encryption_interface::{EncryptionError, EncryptionManagementInterface},
+    secrets_interface::{SecretManagementInterface, SecretsManagementError},
+};
+use masking::{PeekInterface, Secret};
+
+use crate::aws_kms::core::AwsKmsClient;
+
+#[async_trait::async_trait]
+impl EncryptionManagementInterface for AwsKmsClient {
+    async fn encrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError> {
+        self.encrypt(input)
+            .await
+            .change_context(EncryptionError::EncryptionFailed)
+            .map(|val| val.into_bytes())
+    }
+
+    async fn decrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError> {
+        self.decrypt(input)
+            .await
+            .change_context(EncryptionError::DecryptionFailed)
+            .map(|val| val.into_bytes())
+    }
+}
+
+#[async_trait::async_trait]
+impl SecretManagementInterface for AwsKmsClient {
+    async fn get_secret(
+        &self,
+        input: Secret<String>,
+    ) -> CustomResult<Secret<String>, SecretsManagementError> {
+        self.decrypt(input.peek())
+            .await
+            .change_context(SecretsManagementError::FetchSecretFailed)
+            .map(Into::into)
+    }
+}
diff --git a/crates/external_services/src/hashicorp_vault.rs b/crates/external_services/src/hashicorp_vault.rs
index e31c8f01392..5a3ba539689 100644
--- a/crates/external_services/src/hashicorp_vault.rs
+++ b/crates/external_services/src/hashicorp_vault.rs
@@ -1,215 +1,7 @@
 //! Interactions with the HashiCorp Vault
 
-use std::{collections::HashMap, future::Future, pin::Pin};
+pub mod core;
 
-use error_stack::{Report, ResultExt};
-use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};
-
-/// Utilities for supporting decryption of data
 pub mod decrypt;
 
-static HC_CLIENT: tokio::sync::OnceCell<HashiCorpVault> = tokio::sync::OnceCell::const_new();
-
-#[allow(missing_debug_implementations)]
-/// A struct representing a connection to HashiCorp Vault.
-pub struct HashiCorpVault {
-    /// The underlying client used for interacting with HashiCorp Vault.
-    client: VaultClient,
-}
-
-/// Configuration for connecting to HashiCorp Vault.
-#[derive(Clone, Debug, Default, serde::Deserialize)]
-#[serde(default)]
-pub struct HashiCorpVaultConfig {
-    /// The URL of the HashiCorp Vault server.
-    pub url: String,
-    /// The authentication token used to access HashiCorp Vault.
-    pub token: String,
-}
-
-/// Asynchronously retrieves a HashiCorp Vault client based on the provided configuration.
-///
-/// # Parameters
-///
-/// - `config`: A reference to a `HashiCorpVaultConfig` containing the configuration details.
-pub async fn get_hashicorp_client(
-    config: &HashiCorpVaultConfig,
-) -> error_stack::Result<&'static HashiCorpVault, HashiCorpError> {
-    HC_CLIENT
-        .get_or_try_init(|| async { HashiCorpVault::new(config) })
-        .await
-}
-
-/// A trait defining an engine for interacting with HashiCorp Vault.
-pub trait Engine: Sized {
-    /// The associated type representing the return type of the engine's operations.
-    type ReturnType<'b, T>
-    where
-        T: 'b,
-        Self: 'b;
-    /// Reads data from HashiCorp Vault at the specified location.
-    ///
-    /// # Parameters
-    ///
-    /// - `client`: A reference to the HashiCorpVault client.
-    /// - `location`: The location in HashiCorp Vault to read data from.
-    ///
-    /// # Returns
-    ///
-    /// A future representing the result of the read operation.
-    fn read(client: &HashiCorpVault, location: String) -> Self::ReturnType<'_, String>;
-}
-
-/// An implementation of the `Engine` trait for the Key-Value version 2 (Kv2) engine.
-#[derive(Debug)]
-pub enum Kv2 {}
-
-impl Engine for Kv2 {
-    type ReturnType<'b, T: 'b> =
-        Pin<Box<dyn Future<Output = error_stack::Result<T, HashiCorpError>> + Send + 'b>>;
-    fn read(client: &HashiCorpVault, location: String) -> Self::ReturnType<'_, String> {
-        Box::pin(async move {
-            let mut split = location.split(':');
-            let mount = split.next().ok_or(HashiCorpError::IncompleteData)?;
-            let path = split.next().ok_or(HashiCorpError::IncompleteData)?;
-            let key = split.next().unwrap_or("value");
-
-            let mut output =
-                vaultrs::kv2::read::<HashMap<String, String>>(&client.client, mount, path)
-                    .await
-                    .map_err(Into::<Report<_>>::into)
-                    .change_context(HashiCorpError::FetchFailed)?;
-
-            Ok(output.remove(key).ok_or(HashiCorpError::ParseError)?)
-        })
-    }
-}
-
-impl HashiCorpVault {
-    /// Creates a new instance of HashiCorpVault based on the provided configuration.
-    ///
-    /// # Parameters
-    ///
-    /// - `config`: A reference to a `HashiCorpVaultConfig` containing the configuration details.
-    ///
-    pub fn new(config: &HashiCorpVaultConfig) -> error_stack::Result<Self, HashiCorpError> {
-        VaultClient::new(
-            VaultClientSettingsBuilder::default()
-                .address(&config.url)
-                .token(&config.token)
-                .build()
-                .map_err(Into::<Report<_>>::into)
-                .change_context(HashiCorpError::ClientCreationFailed)
-                .attach_printable("Failed while building vault settings")?,
-        )
-        .map_err(Into::<Report<_>>::into)
-        .change_context(HashiCorpError::ClientCreationFailed)
-        .map(|client| Self { client })
-    }
-
-    /// Asynchronously fetches data from HashiCorp Vault using the specified engine.
-    ///
-    /// # Parameters
-    ///
-    /// - `data`: A String representing the location or identifier of the data in HashiCorp Vault.
-    ///
-    /// # Type Parameters
-    ///
-    /// - `En`: The engine type that implements the `Engine` trait.
-    /// - `I`: The type that can be constructed from the retrieved encoded data.
-    ///
-    pub async fn fetch<En, I>(&self, data: String) -> error_stack::Result<I, HashiCorpError>
-    where
-        for<'a> En: Engine<
-                ReturnType<'a, String> = Pin<
-                    Box<
-                        dyn Future<Output = error_stack::Result<String, HashiCorpError>>
-                            + Send
-                            + 'a,
-                    >,
-                >,
-            > + 'a,
-        I: FromEncoded,
-    {
-        let output = En::read(self, data).await?;
-        I::from_encoded(output).ok_or(error_stack::report!(HashiCorpError::HexDecodingFailed))
-    }
-}
-
-/// A trait for types that can be constructed from encoded data in the form of a String.
-pub trait FromEncoded: Sized {
-    /// Constructs an instance of the type from the provided encoded input.
-    ///
-    /// # Parameters
-    ///
-    /// - `input`: A String containing the encoded data.
-    ///
-    /// # Returns
-    ///
-    /// An `Option<Self>` representing the constructed instance if successful, or `None` otherwise.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use your_module::{FromEncoded, masking::Secret, Vec};
-    /// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string());
-    /// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string());
-    /// ```
-    fn from_encoded(input: String) -> Option<Self>;
-}
-
-impl FromEncoded for masking::Secret<String> {
-    fn from_encoded(input: String) -> Option<Self> {
-        Some(input.into())
-    }
-}
-
-impl FromEncoded for Vec<u8> {
-    fn from_encoded(input: String) -> Option<Self> {
-        hex::decode(input).ok()
-    }
-}
-
-/// An enumeration representing various errors that can occur in interactions with HashiCorp Vault.
-#[derive(Debug, thiserror::Error)]
-pub enum HashiCorpError {
-    /// Failed while creating hashicorp client
-    #[error("Failed while creating a new client")]
-    ClientCreationFailed,
-
-    /// Failed while building configurations for hashicorp client
-    #[error("Failed while building configuration")]
-    ConfigurationBuildFailed,
-
-    /// Failed while decoding data to hex format
-    #[error("Failed while decoding hex data")]
-    HexDecodingFailed,
-
-    /// An error occurred when base64 decoding input data.
-    #[error("Failed to base64 decode input data")]
-    Base64DecodingFailed,
-
-    /// An error occurred when KMS decrypting input data.
-    #[error("Failed to KMS decrypt input data")]
-    DecryptionFailed,
-
-    /// The KMS decrypted output does not include a plaintext output.
-    #[error("Missing plaintext KMS decryption output")]
-    MissingPlaintextDecryptionOutput,
-
-    /// An error occurred UTF-8 decoding KMS decrypted output.
-    #[error("Failed to UTF-8 decode decryption output")]
-    Utf8DecodingFailed,
-
-    /// Incomplete data provided to fetch data from hasicorp
-    #[error("Provided information about the value is incomplete")]
-    IncompleteData,
-
-    /// Failed while fetching data from vault
-    #[error("Failed while fetching data from the server")]
-    FetchFailed,
-
-    /// Failed while parsing received data
-    #[error("Failed while parsing the response")]
-    ParseError,
-}
+pub mod implementers;
diff --git a/crates/external_services/src/hashicorp_vault/core.rs b/crates/external_services/src/hashicorp_vault/core.rs
new file mode 100644
index 00000000000..86908b9d3d6
--- /dev/null
+++ b/crates/external_services/src/hashicorp_vault/core.rs
@@ -0,0 +1,227 @@
+//! Interactions with the HashiCorp Vault
+
+use std::{collections::HashMap, future::Future, pin::Pin};
+
+use common_utils::{ext_traits::ConfigExt, fp_utils::when};
+use error_stack::{Report, ResultExt};
+use masking::{PeekInterface, Secret};
+use vaultrs::client::{VaultClient, VaultClientSettingsBuilder};
+
+static HC_CLIENT: tokio::sync::OnceCell<HashiCorpVault> = tokio::sync::OnceCell::const_new();
+
+#[allow(missing_debug_implementations)]
+/// A struct representing a connection to HashiCorp Vault.
+pub struct HashiCorpVault {
+    /// The underlying client used for interacting with HashiCorp Vault.
+    client: VaultClient,
+}
+
+/// Configuration for connecting to HashiCorp Vault.
+#[derive(Clone, Debug, Default, serde::Deserialize)]
+#[serde(default)]
+pub struct HashiCorpVaultConfig {
+    /// The URL of the HashiCorp Vault server.
+    pub url: String,
+    /// The authentication token used to access HashiCorp Vault.
+    pub token: Secret<String>,
+}
+
+impl HashiCorpVaultConfig {
+    /// Verifies that the [`HashiCorpVault`] configuration is usable.
+    pub fn validate(&self) -> Result<(), &'static str> {
+        when(self.url.is_default_or_empty(), || {
+            Err("HashiCorp vault url must not be empty")
+        })?;
+
+        when(self.token.is_default_or_empty(), || {
+            Err("HashiCorp vault token must not be empty")
+        })
+    }
+}
+
+/// Asynchronously retrieves a HashiCorp Vault client based on the provided configuration.
+///
+/// # Parameters
+///
+/// - `config`: A reference to a `HashiCorpVaultConfig` containing the configuration details.
+pub async fn get_hashicorp_client(
+    config: &HashiCorpVaultConfig,
+) -> error_stack::Result<&'static HashiCorpVault, HashiCorpError> {
+    HC_CLIENT
+        .get_or_try_init(|| async { HashiCorpVault::new(config) })
+        .await
+}
+
+/// A trait defining an engine for interacting with HashiCorp Vault.
+pub trait Engine: Sized {
+    /// The associated type representing the return type of the engine's operations.
+    type ReturnType<'b, T>
+    where
+        T: 'b,
+        Self: 'b;
+    /// Reads data from HashiCorp Vault at the specified location.
+    ///
+    /// # Parameters
+    ///
+    /// - `client`: A reference to the HashiCorpVault client.
+    /// - `location`: The location in HashiCorp Vault to read data from.
+    ///
+    /// # Returns
+    ///
+    /// A future representing the result of the read operation.
+    fn read(client: &HashiCorpVault, location: String) -> Self::ReturnType<'_, String>;
+}
+
+/// An implementation of the `Engine` trait for the Key-Value version 2 (Kv2) engine.
+#[derive(Debug)]
+pub enum Kv2 {}
+
+impl Engine for Kv2 {
+    type ReturnType<'b, T: 'b> =
+        Pin<Box<dyn Future<Output = error_stack::Result<T, HashiCorpError>> + Send + 'b>>;
+    fn read(client: &HashiCorpVault, location: String) -> Self::ReturnType<'_, String> {
+        Box::pin(async move {
+            let mut split = location.split(':');
+            let mount = split.next().ok_or(HashiCorpError::IncompleteData)?;
+            let path = split.next().ok_or(HashiCorpError::IncompleteData)?;
+            let key = split.next().unwrap_or("value");
+
+            let mut output =
+                vaultrs::kv2::read::<HashMap<String, String>>(&client.client, mount, path)
+                    .await
+                    .map_err(Into::<Report<_>>::into)
+                    .change_context(HashiCorpError::FetchFailed)?;
+
+            Ok(output.remove(key).ok_or(HashiCorpError::ParseError)?)
+        })
+    }
+}
+
+impl HashiCorpVault {
+    /// Creates a new instance of HashiCorpVault based on the provided configuration.
+    ///
+    /// # Parameters
+    ///
+    /// - `config`: A reference to a `HashiCorpVaultConfig` containing the configuration details.
+    ///
+    pub fn new(config: &HashiCorpVaultConfig) -> error_stack::Result<Self, HashiCorpError> {
+        VaultClient::new(
+            VaultClientSettingsBuilder::default()
+                .address(&config.url)
+                .token(config.token.peek())
+                .build()
+                .map_err(Into::<Report<_>>::into)
+                .change_context(HashiCorpError::ClientCreationFailed)
+                .attach_printable("Failed while building vault settings")?,
+        )
+        .map_err(Into::<Report<_>>::into)
+        .change_context(HashiCorpError::ClientCreationFailed)
+        .map(|client| Self { client })
+    }
+
+    /// Asynchronously fetches data from HashiCorp Vault using the specified engine.
+    ///
+    /// # Parameters
+    ///
+    /// - `data`: A String representing the location or identifier of the data in HashiCorp Vault.
+    ///
+    /// # Type Parameters
+    ///
+    /// - `En`: The engine type that implements the `Engine` trait.
+    /// - `I`: The type that can be constructed from the retrieved encoded data.
+    ///
+    pub async fn fetch<En, I>(&self, data: String) -> error_stack::Result<I, HashiCorpError>
+    where
+        for<'a> En: Engine<
+                ReturnType<'a, String> = Pin<
+                    Box<
+                        dyn Future<Output = error_stack::Result<String, HashiCorpError>>
+                            + Send
+                            + 'a,
+                    >,
+                >,
+            > + 'a,
+        I: FromEncoded,
+    {
+        let output = En::read(self, data).await?;
+        I::from_encoded(output).ok_or(error_stack::report!(HashiCorpError::HexDecodingFailed))
+    }
+}
+
+/// A trait for types that can be constructed from encoded data in the form of a String.
+pub trait FromEncoded: Sized {
+    /// Constructs an instance of the type from the provided encoded input.
+    ///
+    /// # Parameters
+    ///
+    /// - `input`: A String containing the encoded data.
+    ///
+    /// # Returns
+    ///
+    /// An `Option<Self>` representing the constructed instance if successful, or `None` otherwise.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use your_module::{FromEncoded, masking::Secret, Vec};
+    /// let secret_instance = Secret::<String>::from_encoded("encoded_secret_string".to_string());
+    /// let vec_instance = Vec::<u8>::from_encoded("68656c6c6f".to_string());
+    /// ```
+    fn from_encoded(input: String) -> Option<Self>;
+}
+
+impl FromEncoded for Secret<String> {
+    fn from_encoded(input: String) -> Option<Self> {
+        Some(input.into())
+    }
+}
+
+impl FromEncoded for Vec<u8> {
+    fn from_encoded(input: String) -> Option<Self> {
+        hex::decode(input).ok()
+    }
+}
+
+/// An enumeration representing various errors that can occur in interactions with HashiCorp Vault.
+#[derive(Debug, thiserror::Error)]
+pub enum HashiCorpError {
+    /// Failed while creating hashicorp client
+    #[error("Failed while creating a new client")]
+    ClientCreationFailed,
+
+    /// Failed while building configurations for hashicorp client
+    #[error("Failed while building configuration")]
+    ConfigurationBuildFailed,
+
+    /// Failed while decoding data to hex format
+    #[error("Failed while decoding hex data")]
+    HexDecodingFailed,
+
+    /// An error occurred when base64 decoding input data.
+    #[error("Failed to base64 decode input data")]
+    Base64DecodingFailed,
+
+    /// An error occurred when KMS decrypting input data.
+    #[error("Failed to KMS decrypt input data")]
+    DecryptionFailed,
+
+    /// The KMS decrypted output does not include a plaintext output.
+    #[error("Missing plaintext KMS decryption output")]
+    MissingPlaintextDecryptionOutput,
+
+    /// An error occurred UTF-8 decoding KMS decrypted output.
+    #[error("Failed to UTF-8 decode decryption output")]
+    Utf8DecodingFailed,
+
+    /// Incomplete data provided to fetch data from hasicorp
+    #[error("Provided information about the value is incomplete")]
+    IncompleteData,
+
+    /// Failed while fetching data from vault
+    #[error("Failed while fetching data from the server")]
+    FetchFailed,
+
+    /// Failed while parsing received data
+    #[error("Failed while parsing the response")]
+    ParseError,
+}
diff --git a/crates/external_services/src/hashicorp_vault/decrypt.rs b/crates/external_services/src/hashicorp_vault/decrypt.rs
index 1bc1b6ffa16..650b219841f 100644
--- a/crates/external_services/src/hashicorp_vault/decrypt.rs
+++ b/crates/external_services/src/hashicorp_vault/decrypt.rs
@@ -1,7 +1,11 @@
+//! Utilities for supporting decryption of data
+
 use std::{future::Future, pin::Pin};
 
 use masking::ExposeInterface;
 
+use crate::hashicorp_vault::core::{Engine, HashiCorpError, HashiCorpVault};
+
 /// A trait for types that can be asynchronously fetched and decrypted from HashiCorp Vault.
 #[async_trait::async_trait]
 pub trait VaultFetch: Sized {
@@ -14,13 +18,13 @@ pub trait VaultFetch: Sized {
     ///
     async fn fetch_inner<En>(
         self,
-        client: &super::HashiCorpVault,
-    ) -> error_stack::Result<Self, super::HashiCorpError>
+        client: &HashiCorpVault,
+    ) -> error_stack::Result<Self, HashiCorpError>
     where
-        for<'a> En: super::Engine<
+        for<'a> En: Engine<
                 ReturnType<'a, String> = Pin<
                     Box<
-                        dyn Future<Output = error_stack::Result<String, super::HashiCorpError>>
+                        dyn Future<Output = error_stack::Result<String, HashiCorpError>>
                             + Send
                             + 'a,
                     >,
@@ -32,13 +36,13 @@ pub trait VaultFetch: Sized {
 impl VaultFetch for masking::Secret<String> {
     async fn fetch_inner<En>(
         self,
-        client: &super::HashiCorpVault,
-    ) -> error_stack::Result<Self, super::HashiCorpError>
+        client: &HashiCorpVault,
+    ) -> error_stack::Result<Self, HashiCorpError>
     where
-        for<'a> En: super::Engine<
+        for<'a> En: Engine<
                 ReturnType<'a, String> = Pin<
                     Box<
-                        dyn Future<Output = error_stack::Result<String, super::HashiCorpError>>
+                        dyn Future<Output = error_stack::Result<String, HashiCorpError>>
                             + Send
                             + 'a,
                     >,
diff --git a/crates/external_services/src/hashicorp_vault/implementers.rs b/crates/external_services/src/hashicorp_vault/implementers.rs
new file mode 100644
index 00000000000..52fec2bd8d3
--- /dev/null
+++ b/crates/external_services/src/hashicorp_vault/implementers.rs
@@ -0,0 +1,24 @@
+//! Trait implementations for Hashicorp vault client
+
+use common_utils::errors::CustomResult;
+use error_stack::ResultExt;
+use hyperswitch_interfaces::secrets_interface::{
+    SecretManagementInterface, SecretsManagementError,
+};
+use masking::{ExposeInterface, Secret};
+
+use crate::hashicorp_vault::core::{HashiCorpVault, Kv2};
+
+#[async_trait::async_trait]
+impl SecretManagementInterface for HashiCorpVault {
+    async fn get_secret(
+        &self,
+        input: Secret<String>,
+    ) -> CustomResult<Secret<String>, SecretsManagementError> {
+        self.fetch::<Kv2, Secret<String>>(input.expose())
+            .await
+            .map(|val| val.expose().to_owned())
+            .change_context(SecretsManagementError::FetchSecretFailed)
+            .map(Into::into)
+    }
+}
diff --git a/crates/external_services/src/lib.rs b/crates/external_services/src/lib.rs
index cdabdeb49ae..33ab7541974 100644
--- a/crates/external_services/src/lib.rs
+++ b/crates/external_services/src/lib.rs
@@ -13,6 +13,10 @@ pub mod file_storage;
 #[cfg(feature = "hashicorp-vault")]
 pub mod hashicorp_vault;
 
+pub mod no_encryption;
+
+pub mod managers;
+
 /// Crate specific constants
 #[cfg(feature = "aws_kms")]
 pub mod consts {
diff --git a/crates/external_services/src/managers.rs b/crates/external_services/src/managers.rs
new file mode 100644
index 00000000000..cb33d7bbf38
--- /dev/null
+++ b/crates/external_services/src/managers.rs
@@ -0,0 +1,5 @@
+//! Config and client managers
+
+pub mod encryption_management;
+
+pub mod secrets_management;
diff --git a/crates/external_services/src/managers/encryption_management.rs b/crates/external_services/src/managers/encryption_management.rs
new file mode 100644
index 00000000000..4612190926c
--- /dev/null
+++ b/crates/external_services/src/managers/encryption_management.rs
@@ -0,0 +1,53 @@
+//!
+//! Encryption management util module
+//!
+
+use common_utils::errors::CustomResult;
+use hyperswitch_interfaces::encryption_interface::{
+    EncryptionError, EncryptionManagementInterface,
+};
+
+#[cfg(feature = "aws_kms")]
+use crate::aws_kms;
+use crate::no_encryption::core::NoEncryption;
+
+/// Enum representing configuration options for encryption management.
+#[derive(Debug, Clone, Default, serde::Deserialize)]
+#[serde(tag = "encryption_manager")]
+#[serde(rename_all = "snake_case")]
+pub enum EncryptionManagementConfig {
+    /// AWS KMS configuration
+    #[cfg(feature = "aws_kms")]
+    AwsKms {
+        /// AWS KMS config
+        aws_kms: aws_kms::core::AwsKmsConfig,
+    },
+
+    /// Variant representing no encryption
+    #[default]
+    NoEncryption,
+}
+
+impl EncryptionManagementConfig {
+    /// Verifies that the client configuration is usable
+    pub fn validate(&self) -> Result<(), &'static str> {
+        match self {
+            #[cfg(feature = "aws_kms")]
+            Self::AwsKms { aws_kms } => aws_kms.validate(),
+
+            Self::NoEncryption => Ok(()),
+        }
+    }
+
+    /// Retrieves the appropriate encryption client based on the configuration.
+    pub async fn get_encryption_management_client(
+        &self,
+    ) -> CustomResult<Box<dyn EncryptionManagementInterface>, EncryptionError> {
+        Ok(match self {
+            #[cfg(feature = "aws_kms")]
+            Self::AwsKms { aws_kms } => Box::new(aws_kms::core::AwsKmsClient::new(aws_kms).await),
+
+            Self::NoEncryption => Box::new(NoEncryption),
+        })
+    }
+}
diff --git a/crates/external_services/src/managers/secrets_management.rs b/crates/external_services/src/managers/secrets_management.rs
new file mode 100644
index 00000000000..b79046b4c75
--- /dev/null
+++ b/crates/external_services/src/managers/secrets_management.rs
@@ -0,0 +1,72 @@
+//!
+//! Secrets management util module
+//!
+
+use common_utils::errors::CustomResult;
+#[cfg(feature = "hashicorp-vault")]
+use error_stack::ResultExt;
+use hyperswitch_interfaces::secrets_interface::{
+    SecretManagementInterface, SecretsManagementError,
+};
+
+#[cfg(feature = "aws_kms")]
+use crate::aws_kms;
+#[cfg(feature = "hashicorp-vault")]
+use crate::hashicorp_vault;
+use crate::no_encryption::core::NoEncryption;
+
+/// Enum representing configuration options for secrets management.
+#[derive(Debug, Clone, Default, serde::Deserialize)]
+#[serde(tag = "secrets_manager")]
+#[serde(rename_all = "snake_case")]
+pub enum SecretsManagementConfig {
+    /// AWS KMS configuration
+    #[cfg(feature = "aws_kms")]
+    AwsKms {
+        /// AWS KMS config
+        aws_kms: aws_kms::core::AwsKmsConfig,
+    },
+
+    /// HashiCorp-Vault configuration
+    #[cfg(feature = "hashicorp-vault")]
+    HashiCorpVault {
+        /// HC-Vault config
+        hc_vault: hashicorp_vault::core::HashiCorpVaultConfig,
+    },
+
+    /// Variant representing no encryption
+    #[default]
+    NoEncryption,
+}
+
+impl SecretsManagementConfig {
+    /// Verifies that the client configuration is usable
+    pub fn validate(&self) -> Result<(), &'static str> {
+        match self {
+            #[cfg(feature = "aws_kms")]
+            Self::AwsKms { aws_kms } => aws_kms.validate(),
+            #[cfg(feature = "hashicorp-vault")]
+            Self::HashiCorpVault { hc_vault } => hc_vault.validate(),
+            Self::NoEncryption => Ok(()),
+        }
+    }
+
+    /// Retrieves the appropriate secret management client based on the configuration.
+    pub async fn get_secret_management_client(
+        &self,
+    ) -> CustomResult<Box<dyn SecretManagementInterface>, SecretsManagementError> {
+        match self {
+            #[cfg(feature = "aws_kms")]
+            Self::AwsKms { aws_kms } => {
+                Ok(Box::new(aws_kms::core::AwsKmsClient::new(aws_kms).await))
+            }
+            #[cfg(feature = "hashicorp-vault")]
+            Self::HashiCorpVault { hc_vault } => {
+                hashicorp_vault::core::HashiCorpVault::new(hc_vault)
+                    .change_context(SecretsManagementError::ClientCreationFailed)
+                    .map(|inner| -> Box<dyn SecretManagementInterface> { Box::new(inner) })
+            }
+            Self::NoEncryption => Ok(Box::new(NoEncryption)),
+        }
+    }
+}
diff --git a/crates/external_services/src/no_encryption.rs b/crates/external_services/src/no_encryption.rs
new file mode 100644
index 00000000000..17c29618f89
--- /dev/null
+++ b/crates/external_services/src/no_encryption.rs
@@ -0,0 +1,7 @@
+//!
+//! No encryption functionalities
+//!
+
+pub mod core;
+
+pub mod implementers;
diff --git a/crates/external_services/src/no_encryption/core.rs b/crates/external_services/src/no_encryption/core.rs
new file mode 100644
index 00000000000..a55815c03f9
--- /dev/null
+++ b/crates/external_services/src/no_encryption/core.rs
@@ -0,0 +1,17 @@
+//! No encryption core functionalities
+
+/// No encryption type
+#[derive(Debug, Clone)]
+pub struct NoEncryption;
+
+impl NoEncryption {
+    /// Encryption functionality
+    pub fn encrypt(&self, data: impl AsRef<[u8]>) -> Vec<u8> {
+        data.as_ref().into()
+    }
+
+    /// Decryption functionality
+    pub fn decrypt(&self, data: impl AsRef<[u8]>) -> Vec<u8> {
+        data.as_ref().into()
+    }
+}
diff --git a/crates/external_services/src/no_encryption/implementers.rs b/crates/external_services/src/no_encryption/implementers.rs
new file mode 100644
index 00000000000..f67c7c85fd5
--- /dev/null
+++ b/crates/external_services/src/no_encryption/implementers.rs
@@ -0,0 +1,36 @@
+//! Trait implementations for No encryption client
+
+use common_utils::errors::CustomResult;
+use error_stack::{IntoReport, ResultExt};
+use hyperswitch_interfaces::{
+    encryption_interface::{EncryptionError, EncryptionManagementInterface},
+    secrets_interface::{SecretManagementInterface, SecretsManagementError},
+};
+use masking::{ExposeInterface, Secret};
+
+use crate::no_encryption::core::NoEncryption;
+
+#[async_trait::async_trait]
+impl EncryptionManagementInterface for NoEncryption {
+    async fn encrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError> {
+        Ok(self.encrypt(input))
+    }
+
+    async fn decrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError> {
+        Ok(self.decrypt(input))
+    }
+}
+
+#[async_trait::async_trait]
+impl SecretManagementInterface for NoEncryption {
+    async fn get_secret(
+        &self,
+        input: Secret<String>,
+    ) -> CustomResult<Secret<String>, SecretsManagementError> {
+        String::from_utf8(self.decrypt(input.expose()))
+            .map(Into::into)
+            .into_report()
+            .change_context(SecretsManagementError::FetchSecretFailed)
+            .attach_printable("Failed to convert decrypted value to UTF-8")
+    }
+}
diff --git a/crates/hyperswitch_interfaces/Cargo.toml b/crates/hyperswitch_interfaces/Cargo.toml
new file mode 100644
index 00000000000..855cf63917f
--- /dev/null
+++ b/crates/hyperswitch_interfaces/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "hyperswitch_interfaces"
+version = "0.1.0"
+edition.workspace = true
+rust-version.workspace = true
+readme = "README.md"
+license.workspace = true
+
+[dependencies]
+async-trait = "0.1.68"
+dyn-clone = "1.0.11"
+serde = { version = "1.0.193", features = ["derive"] }
+thiserror = "1.0.40"
+
+# First party crates
+common_utils = { version = "0.1.0", path = "../common_utils" }
+masking = { version = "0.1.0", path = "../masking" }
diff --git a/crates/hyperswitch_interfaces/README.md b/crates/hyperswitch_interfaces/README.md
new file mode 100644
index 00000000000..e96e3eabe2a
--- /dev/null
+++ b/crates/hyperswitch_interfaces/README.md
@@ -0,0 +1,3 @@
+# Hyperswitch Interfaces
+
+This crate includes interfaces and its error types
diff --git a/crates/hyperswitch_interfaces/src/encryption_interface.rs b/crates/hyperswitch_interfaces/src/encryption_interface.rs
new file mode 100644
index 00000000000..1993019a213
--- /dev/null
+++ b/crates/hyperswitch_interfaces/src/encryption_interface.rs
@@ -0,0 +1,29 @@
+//! Encryption related interface and error types
+
+#![warn(missing_docs, missing_debug_implementations)]
+
+use common_utils::errors::CustomResult;
+
+/// Trait defining the interface for encryption management
+#[async_trait::async_trait]
+pub trait EncryptionManagementInterface: Sync + Send + dyn_clone::DynClone {
+    /// Encrypt the given input data
+    async fn encrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError>;
+
+    /// Decrypt the given input data
+    async fn decrypt(&self, input: &[u8]) -> CustomResult<Vec<u8>, EncryptionError>;
+}
+
+dyn_clone::clone_trait_object!(EncryptionManagementInterface);
+
+/// Errors that may occur during above encryption functionalities
+#[derive(Debug, thiserror::Error)]
+pub enum EncryptionError {
+    /// An error occurred when encrypting input data.
+    #[error("Failed to encrypt input data")]
+    EncryptionFailed,
+
+    /// An error occurred when decrypting input data.
+    #[error("Failed to decrypt input data")]
+    DecryptionFailed,
+}
diff --git a/crates/hyperswitch_interfaces/src/lib.rs b/crates/hyperswitch_interfaces/src/lib.rs
new file mode 100644
index 00000000000..3f7b8d41c3e
--- /dev/null
+++ b/crates/hyperswitch_interfaces/src/lib.rs
@@ -0,0 +1,7 @@
+//! Hyperswitch interface
+
+#![warn(missing_docs, missing_debug_implementations)]
+
+pub mod secrets_interface;
+
+pub mod encryption_interface;
diff --git a/crates/hyperswitch_interfaces/src/secrets_interface.rs b/crates/hyperswitch_interfaces/src/secrets_interface.rs
new file mode 100644
index 00000000000..761981bedda
--- /dev/null
+++ b/crates/hyperswitch_interfaces/src/secrets_interface.rs
@@ -0,0 +1,36 @@
+//! Secrets management interface
+
+pub mod secret_handler;
+
+pub mod secret_state;
+
+use common_utils::errors::CustomResult;
+use masking::Secret;
+
+/// Trait defining the interface for managing application secrets
+#[async_trait::async_trait]
+pub trait SecretManagementInterface: Send + Sync {
+    /// Given an input, encrypt/store the secret
+    // async fn store_secret(
+    //     &self,
+    //     input: Secret<String>,
+    // ) -> CustomResult<String, SecretsManagementError>;
+
+    /// Given an input, decrypt/retrieve the secret
+    async fn get_secret(
+        &self,
+        input: Secret<String>,
+    ) -> CustomResult<Secret<String>, SecretsManagementError>;
+}
+
+/// Errors that may occur during secret management
+#[derive(Debug, thiserror::Error)]
+pub enum SecretsManagementError {
+    /// An error occurred when retrieving raw data.
+    #[error("Failed to fetch the raw data")]
+    FetchSecretFailed,
+
+    /// Failed while creating kms client
+    #[error("Failed while creating a secrets management client")]
+    ClientCreationFailed,
+}
diff --git a/crates/hyperswitch_interfaces/src/secrets_interface/secret_handler.rs b/crates/hyperswitch_interfaces/src/secrets_interface/secret_handler.rs
new file mode 100644
index 00000000000..a0915b8de69
--- /dev/null
+++ b/crates/hyperswitch_interfaces/src/secrets_interface/secret_handler.rs
@@ -0,0 +1,21 @@
+//! Module containing trait for raw secret retrieval
+
+use common_utils::errors::CustomResult;
+
+use crate::secrets_interface::{
+    secret_state::{RawSecret, SecretStateContainer, SecuredSecret},
+    SecretManagementInterface, SecretsManagementError,
+};
+
+/// Trait defining the interface for retrieving a raw secret value, given a secured value
+#[async_trait::async_trait]
+pub trait SecretsHandler
+where
+    Self: Sized,
+{
+    /// Construct `Self` with raw secret value and transitions its type from `SecuredSecret` to `RawSecret`
+    async fn convert_to_raw_secret(
+        value: SecretStateContainer<Self, SecuredSecret>,
+        kms_client: Box<dyn SecretManagementInterface>,
+    ) -> CustomResult<SecretStateContainer<Self, RawSecret>, SecretsManagementError>;
+}
diff --git a/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs b/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs
new file mode 100644
index 00000000000..6d3f75500af
--- /dev/null
+++ b/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs
@@ -0,0 +1,71 @@
+//! Module to manage encrypted and decrypted states for a given type.
+
+use std::marker::PhantomData;
+
+use serde::{Deserialize, Deserializer};
+
+/// Trait defining the states of a secret
+pub trait SecretState {}
+
+/// Decrypted state
+#[derive(Debug, Clone, Deserialize)]
+pub enum RawSecret {}
+
+/// Encrypted state
+#[derive(Debug, Clone, Deserialize)]
+pub enum SecuredSecret {}
+
+impl SecretState for RawSecret {}
+impl SecretState for SecuredSecret {}
+
+/// Struct for managing the encrypted and decrypted states of a given type
+#[derive(Debug, Clone, Default)]
+pub struct SecretStateContainer<T, S: SecretState> {
+    inner: T,
+    marker: PhantomData<S>,
+}
+
+impl<T: Clone, S: SecretState> SecretStateContainer<T, S> {
+    ///
+    /// Get the inner data while consuming self
+    ///
+    #[inline]
+    pub fn into_inner(self) -> T {
+        self.inner
+    }
+
+    ///
+    /// Get the reference to inner value
+    ///
+    #[inline]
+    pub fn get_inner(&self) -> &T {
+        &self.inner
+    }
+}
+
+impl<'de, T: Deserialize<'de>, S: SecretState> Deserialize<'de> for SecretStateContainer<T, S> {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let val = Deserialize::deserialize(deserializer)?;
+        Ok(Self {
+            inner: val,
+            marker: PhantomData,
+        })
+    }
+}
+
+impl<T> SecretStateContainer<T, SecuredSecret> {
+    /// Transition the secret state from `SecuredSecret` to `RawSecret`
+    pub fn transition_state(
+        mut self,
+        decryptor_fn: impl FnOnce(T) -> T,
+    ) -> SecretStateContainer<T, RawSecret> {
+        self.inner = decryptor_fn(self.inner);
+        SecretStateContainer {
+            inner: self.inner,
+            marker: PhantomData,
+        }
+    }
+}
diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml
index 9b345217bb5..690a0676fa6 100644
--- a/crates/router/Cargo.toml
+++ b/crates/router/Cargo.toml
@@ -111,6 +111,7 @@ diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_
 euclid = { version = "0.1.0", path = "../euclid", features = ["valued_jit"] }
 pm_auth = { version = "0.1.0", path = "../pm_auth", package = "pm_auth" }
 external_services = { version = "0.1.0", path = "../external_services" }
+hyperswitch_interfaces = { version = "0.1.0", path = "../hyperswitch_interfaces" }
 kgraph_utils = { version = "0.1.0", path = "../kgraph_utils" }
 masking = { version = "0.1.0", path = "../masking" }
 redis_interface = { version = "0.1.0", path = "../redis_interface" }
diff --git a/crates/router/src/configs/aws_kms.rs b/crates/router/src/configs/aws_kms.rs
index 5e37f2a4dd6..9bb5fcc6f20 100644
--- a/crates/router/src/configs/aws_kms.rs
+++ b/crates/router/src/configs/aws_kms.rs
@@ -1,5 +1,8 @@
 use common_utils::errors::CustomResult;
-use external_services::aws_kms::{decrypt::AwsKmsDecrypt, AwsKmsClient, AwsKmsError};
+use external_services::aws_kms::{
+    core::{AwsKmsClient, AwsKmsError},
+    decrypt::AwsKmsDecrypt,
+};
 use masking::ExposeInterface;
 
 use crate::configs::settings;
diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs
index 71cd61ffa80..82237e7a887 100644
--- a/crates/router/src/configs/defaults.rs
+++ b/crates/router/src/configs/defaults.rs
@@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
 
 use api_models::{enums, payment_methods::RequiredFieldInfo};
 #[cfg(feature = "aws_kms")]
-use external_services::aws_kms::AwsKmsValue;
+use external_services::aws_kms::core::AwsKmsValue;
 
 use super::settings::{ConnectorFields, Password, PaymentMethodType, RequiredFieldFinal};
 
diff --git a/crates/router/src/configs/hc_vault.rs b/crates/router/src/configs/hc_vault.rs
index f20d8e79ed8..fa6596f7494 100644
--- a/crates/router/src/configs/hc_vault.rs
+++ b/crates/router/src/configs/hc_vault.rs
@@ -1,5 +1,6 @@
 use external_services::hashicorp_vault::{
-    decrypt::VaultFetch, Engine, HashiCorpError, HashiCorpVault,
+    core::{Engine, HashiCorpError, HashiCorpVault},
+    decrypt::VaultFetch,
 };
 use masking::ExposeInterface;
 
diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs
index 2572d764d06..13c3ba23e1d 100644
--- a/crates/router/src/configs/settings.rs
+++ b/crates/router/src/configs/settings.rs
@@ -12,9 +12,15 @@ use config::{Environment, File};
 use external_services::aws_kms;
 #[cfg(feature = "email")]
 use external_services::email::EmailSettings;
-use external_services::file_storage::FileStorageConfig;
 #[cfg(feature = "hashicorp-vault")]
 use external_services::hashicorp_vault;
+use external_services::{
+    file_storage::FileStorageConfig,
+    managers::{
+        encryption_management::EncryptionManagementConfig,
+        secrets_management::SecretsManagementConfig,
+    },
+};
 use redis_interface::RedisSettings;
 pub use router_env::config::{Log, LogConsole, LogFile, LogTelemetry};
 use rust_decimal::Decimal;
@@ -30,7 +36,7 @@ use crate::{
     events::EventsConfig,
 };
 #[cfg(feature = "aws_kms")]
-pub type Password = aws_kms::AwsKmsValue;
+pub type Password = aws_kms::core::AwsKmsValue;
 #[cfg(not(feature = "aws_kms"))]
 pub type Password = masking::Secret<String>;
 
@@ -89,10 +95,12 @@ pub struct Settings {
     pub bank_config: BankRedirectConfig,
     pub api_keys: ApiKeys,
     #[cfg(feature = "aws_kms")]
-    pub kms: aws_kms::AwsKmsConfig,
+    pub kms: aws_kms::core::AwsKmsConfig,
     pub file_storage: FileStorageConfig,
+    pub encryption_management: EncryptionManagementConfig,
+    pub secrets_management: SecretsManagementConfig,
     #[cfg(feature = "hashicorp-vault")]
-    pub hc_vault: hashicorp_vault::HashiCorpVaultConfig,
+    pub hc_vault: hashicorp_vault::core::HashiCorpVaultConfig,
     pub tokenization: TokenizationConfig,
     pub connector_customer: ConnectorCustomer,
     #[cfg(feature = "dummy_connector")]
@@ -368,11 +376,11 @@ pub struct Secrets {
     pub recon_admin_api_key: String,
     pub master_enc_key: Password,
     #[cfg(feature = "aws_kms")]
-    pub kms_encrypted_jwt_secret: aws_kms::AwsKmsValue,
+    pub kms_encrypted_jwt_secret: aws_kms::core::AwsKmsValue,
     #[cfg(feature = "aws_kms")]
-    pub kms_encrypted_admin_api_key: aws_kms::AwsKmsValue,
+    pub kms_encrypted_admin_api_key: aws_kms::core::AwsKmsValue,
     #[cfg(feature = "aws_kms")]
-    pub kms_encrypted_recon_admin_api_key: aws_kms::AwsKmsValue,
+    pub kms_encrypted_recon_admin_api_key: aws_kms::core::AwsKmsValue,
 }
 
 #[derive(Debug, Deserialize, Clone)]
@@ -598,7 +606,7 @@ pub struct ApiKeys {
     /// Base64-encoded (KMS encrypted) ciphertext of the key used for calculating hashes of API
     /// keys
     #[cfg(feature = "aws_kms")]
-    pub kms_encrypted_hash_key: aws_kms::AwsKmsValue,
+    pub kms_encrypted_hash_key: aws_kms::core::AwsKmsValue,
 
     /// Hex-encoded 32-byte long (64 characters long when hex-encoded) key used for calculating
     /// hashes of API keys
@@ -724,6 +732,14 @@ impl Settings {
 
         self.lock_settings.validate()?;
         self.events.validate()?;
+
+        self.encryption_management
+            .validate()
+            .map_err(|err| ApplicationError::InvalidConfigurationValueError(err.into()))?;
+
+        self.secrets_management
+            .validate()
+            .map_err(|err| ApplicationError::InvalidConfigurationValueError(err.into()))?;
         Ok(())
     }
 }
diff --git a/crates/router/src/core/api_keys.rs b/crates/router/src/core/api_keys.rs
index 162f8bed0f8..b694d1291a8 100644
--- a/crates/router/src/core/api_keys.rs
+++ b/crates/router/src/core/api_keys.rs
@@ -38,9 +38,9 @@ static HASH_KEY: tokio::sync::OnceCell<StrongSecret<[u8; PlaintextApiKey::HASH_K
 
 pub async fn get_hash_key(
     api_key_config: &settings::ApiKeys,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::core::AwsKmsClient,
     #[cfg(feature = "hashicorp-vault")]
-    hc_client: &external_services::hashicorp_vault::HashiCorpVault,
+    hc_client: &external_services::hashicorp_vault::core::HashiCorpVault,
 ) -> errors::RouterResult<&'static StrongSecret<[u8; PlaintextApiKey::HASH_KEY_LEN]>> {
     HASH_KEY
         .get_or_try_init(|| async {
@@ -57,7 +57,7 @@ pub async fn get_hash_key(
 
             #[cfg(feature = "hashicorp-vault")]
             let hash_key = hash_key
-                .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+                .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)?;
 
@@ -153,9 +153,9 @@ impl PlaintextApiKey {
 #[instrument(skip_all)]
 pub async fn create_api_key(
     state: AppState,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::core::AwsKmsClient,
     #[cfg(feature = "hashicorp-vault")]
-    hc_client: &external_services::hashicorp_vault::HashiCorpVault,
+    hc_client: &external_services::hashicorp_vault::core::HashiCorpVault,
     api_key: api::CreateApiKeyRequest,
     merchant_id: String,
 ) -> RouterResponse<api::CreateApiKeyResponse> {
@@ -590,9 +590,9 @@ mod tests {
         let hash_key = get_hash_key(
             &settings.api_keys,
             #[cfg(feature = "aws_kms")]
-            external_services::aws_kms::get_aws_kms_client(&settings.kms).await,
+            external_services::aws_kms::core::get_aws_kms_client(&settings.kms).await,
             #[cfg(feature = "hashicorp-vault")]
-            external_services::hashicorp_vault::get_hashicorp_client(&settings.hc_vault)
+            external_services::hashicorp_vault::core::get_hashicorp_client(&settings.hc_vault)
                 .await
                 .unwrap(),
         )
diff --git a/crates/router/src/core/blocklist/utils.rs b/crates/router/src/core/blocklist/utils.rs
index 43701c80786..733b565beed 100644
--- a/crates/router/src/core/blocklist/utils.rs
+++ b/crates/router/src/core/blocklist/utils.rs
@@ -48,7 +48,7 @@ pub async fn delete_entry_from_blocklist(
                 })?;
 
             #[cfg(feature = "aws_kms")]
-            let decrypted_fingerprint = aws_kms::get_aws_kms_client(&state.conf.kms)
+            let decrypted_fingerprint = aws_kms::core::get_aws_kms_client(&state.conf.kms)
                 .await
                 .decrypt(blocklist_fingerprint.encrypted_fingerprint)
                 .await
@@ -244,7 +244,7 @@ pub async fn insert_entry_into_blocklist(
                 })?;
 
             #[cfg(feature = "aws_kms")]
-            let decrypted_fingerprint = aws_kms::get_aws_kms_client(&state.conf.kms)
+            let decrypted_fingerprint = aws_kms::core::get_aws_kms_client(&state.conf.kms)
                 .await
                 .decrypt(blocklist_fingerprint.encrypted_fingerprint)
                 .await
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index 062c58e056c..479a0685a97 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -189,12 +189,13 @@ async fn create_applepay_session_token(
                         common_merchant_identifier,
                     ) = async {
                         #[cfg(feature = "hashicorp-vault")]
-                        let client = external_services::hashicorp_vault::get_hashicorp_client(
-                            &state.conf.hc_vault,
-                        )
-                        .await
-                        .change_context(errors::ApiErrorResponse::InternalServerError)
-                        .attach_printable("Failed while building hashicorp client")?;
+                        let client =
+                            external_services::hashicorp_vault::core::get_hashicorp_client(
+                                &state.conf.hc_vault,
+                            )
+                            .await
+                            .change_context(errors::ApiErrorResponse::InternalServerError)
+                            .attach_printable("Failed while building hashicorp client")?;
 
                         #[cfg(feature = "hashicorp-vault")]
                         {
@@ -206,7 +207,7 @@ async fn create_applepay_session_token(
                                         .apple_pay_merchant_cert
                                         .clone(),
                                 )
-                                .fetch_inner::<hashicorp_vault::Kv2>(client)
+                                .fetch_inner::<hashicorp_vault::core::Kv2>(client)
                                 .await
                                 .change_context(errors::ApiErrorResponse::InternalServerError)?
                                 .expose(),
@@ -217,7 +218,7 @@ async fn create_applepay_session_token(
                                         .apple_pay_merchant_cert_key
                                         .clone(),
                                 )
-                                .fetch_inner::<hashicorp_vault::Kv2>(client)
+                                .fetch_inner::<hashicorp_vault::core::Kv2>(client)
                                 .await
                                 .change_context(errors::ApiErrorResponse::InternalServerError)?
                                 .expose(),
@@ -228,7 +229,7 @@ async fn create_applepay_session_token(
                                         .common_merchant_identifier
                                         .clone(),
                                 )
-                                .fetch_inner::<hashicorp_vault::Kv2>(client)
+                                .fetch_inner::<hashicorp_vault::core::Kv2>(client)
                                 .await
                                 .change_context(errors::ApiErrorResponse::InternalServerError)?
                                 .expose(),
@@ -260,7 +261,7 @@ async fn create_applepay_session_token(
 
                     #[cfg(feature = "aws_kms")]
                     let decrypted_apple_pay_merchant_cert =
-                        aws_kms::get_aws_kms_client(&state.conf.kms)
+                        aws_kms::core::get_aws_kms_client(&state.conf.kms)
                             .await
                             .decrypt(apple_pay_merchant_cert)
                             .await
@@ -269,7 +270,7 @@ async fn create_applepay_session_token(
 
                     #[cfg(feature = "aws_kms")]
                     let decrypted_apple_pay_merchant_cert_key =
-                        aws_kms::get_aws_kms_client(&state.conf.kms)
+                        aws_kms::core::get_aws_kms_client(&state.conf.kms)
                             .await
                             .decrypt(apple_pay_merchant_cert_key)
                             .await
@@ -280,7 +281,7 @@ async fn create_applepay_session_token(
 
                     #[cfg(feature = "aws_kms")]
                     let decrypted_merchant_identifier =
-                        aws_kms::get_aws_kms_client(&state.conf.kms)
+                        aws_kms::core::get_aws_kms_client(&state.conf.kms)
                             .await
                             .decrypt(common_merchant_identifier)
                             .await
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 7ec1f5e9213..b93d959eb8d 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -3537,16 +3537,17 @@ impl ApplePayData {
     ) -> CustomResult<String, errors::ApplePayDecryptionError> {
         let apple_pay_ppc = async {
             #[cfg(feature = "hashicorp-vault")]
-            let client =
-                external_services::hashicorp_vault::get_hashicorp_client(&state.conf.hc_vault)
-                    .await
-                    .change_context(errors::ApplePayDecryptionError::DecryptionFailed)
-                    .attach_printable("Failed while creating client")?;
+            let client = external_services::hashicorp_vault::core::get_hashicorp_client(
+                &state.conf.hc_vault,
+            )
+            .await
+            .change_context(errors::ApplePayDecryptionError::DecryptionFailed)
+            .attach_printable("Failed while creating client")?;
 
             #[cfg(feature = "hashicorp-vault")]
             let output =
                 masking::Secret::new(state.conf.applepay_decrypt_keys.apple_pay_ppc.clone())
-                    .fetch_inner::<hashicorp_vault::Kv2>(client)
+                    .fetch_inner::<hashicorp_vault::core::Kv2>(client)
                     .await
                     .change_context(errors::ApplePayDecryptionError::DecryptionFailed)?
                     .expose();
@@ -3559,7 +3560,7 @@ impl ApplePayData {
         .await?;
 
         #[cfg(feature = "aws_kms")]
-        let cert_data = aws_kms::get_aws_kms_client(&state.conf.kms)
+        let cert_data = aws_kms::core::get_aws_kms_client(&state.conf.kms)
             .await
             .decrypt(&apple_pay_ppc)
             .await
@@ -3620,16 +3621,17 @@ impl ApplePayData {
 
         let apple_pay_ppc_key = async {
             #[cfg(feature = "hashicorp-vault")]
-            let client =
-                external_services::hashicorp_vault::get_hashicorp_client(&state.conf.hc_vault)
-                    .await
-                    .change_context(errors::ApplePayDecryptionError::DecryptionFailed)
-                    .attach_printable("Failed while creating client")?;
+            let client = external_services::hashicorp_vault::core::get_hashicorp_client(
+                &state.conf.hc_vault,
+            )
+            .await
+            .change_context(errors::ApplePayDecryptionError::DecryptionFailed)
+            .attach_printable("Failed while creating client")?;
 
             #[cfg(feature = "hashicorp-vault")]
             let output =
                 masking::Secret::new(state.conf.applepay_decrypt_keys.apple_pay_ppc_key.clone())
-                    .fetch_inner::<hashicorp_vault::Kv2>(client)
+                    .fetch_inner::<hashicorp_vault::core::Kv2>(client)
                     .await
                     .change_context(errors::ApplePayDecryptionError::DecryptionFailed)
                     .attach_printable("Failed while creating client")?
@@ -3643,7 +3645,7 @@ impl ApplePayData {
         .await?;
 
         #[cfg(feature = "aws_kms")]
-        let decrypted_apple_pay_ppc_key = aws_kms::get_aws_kms_client(&state.conf.kms)
+        let decrypted_apple_pay_ppc_key = aws_kms::core::get_aws_kms_client(&state.conf.kms)
             .await
             .decrypt(&apple_pay_ppc_key)
             .await
diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs
index f77d5120812..f00c452f3ea 100644
--- a/crates/router/src/core/pm_auth.rs
+++ b/crates/router/src/core/pm_auth.rs
@@ -349,14 +349,15 @@ async fn store_bank_details_in_payment_methods(
 
     let pm_auth_key = async {
         #[cfg(feature = "hashicorp-vault")]
-        let client = external_services::hashicorp_vault::get_hashicorp_client(&state.conf.hc_vault)
-            .await
-            .change_context(ApiErrorResponse::InternalServerError)
-            .attach_printable("Failed while creating client")?;
+        let client =
+            external_services::hashicorp_vault::core::get_hashicorp_client(&state.conf.hc_vault)
+                .await
+                .change_context(ApiErrorResponse::InternalServerError)
+                .attach_printable("Failed while creating client")?;
 
         #[cfg(feature = "hashicorp-vault")]
         let output = masking::Secret::new(state.conf.payment_method_auth.pm_auth_key.clone())
-            .fetch_inner::<hashicorp_vault::Kv2>(client)
+            .fetch_inner::<hashicorp_vault::core::Kv2>(client)
             .await
             .change_context(ApiErrorResponse::InternalServerError)?
             .expose();
@@ -369,7 +370,7 @@ async fn store_bank_details_in_payment_methods(
     .await?;
 
     #[cfg(feature = "aws_kms")]
-    let pm_auth_key = aws_kms::get_aws_kms_client(&state.conf.kms)
+    let pm_auth_key = aws_kms::core::get_aws_kms_client(&state.conf.kms)
         .await
         .decrypt(pm_auth_key)
         .await
diff --git a/crates/router/src/core/verification.rs b/crates/router/src/core/verification.rs
index 0ed70e6e0c6..79513bfb308 100644
--- a/crates/router/src/core/verification.rs
+++ b/crates/router/src/core/verification.rs
@@ -13,7 +13,7 @@ pub async fn verify_merchant_creds_for_applepay(
     state: AppState,
     _req: &actix_web::HttpRequest,
     body: verifications::ApplepayMerchantVerificationRequest,
-    kms_config: &aws_kms::AwsKmsConfig,
+    kms_config: &aws_kms::core::AwsKmsConfig,
     merchant_id: String,
 ) -> CustomResult<
     services::ApplicationResponse<ApplepayMerchantResponse>,
@@ -27,19 +27,19 @@ pub async fn verify_merchant_creds_for_applepay(
     let encrypted_key = &state.conf.applepay_merchant_configs.merchant_cert_key;
     let applepay_endpoint = &state.conf.applepay_merchant_configs.applepay_endpoint;
 
-    let applepay_internal_merchant_identifier = aws_kms::get_aws_kms_client(kms_config)
+    let applepay_internal_merchant_identifier = aws_kms::core::get_aws_kms_client(kms_config)
         .await
         .decrypt(encrypted_merchant_identifier)
         .await
         .change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
 
-    let cert_data = aws_kms::get_aws_kms_client(kms_config)
+    let cert_data = aws_kms::core::get_aws_kms_client(kms_config)
         .await
         .decrypt(encrypted_cert)
         .await
         .change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
 
-    let key_data = aws_kms::get_aws_kms_client(kms_config)
+    let key_data = aws_kms::core::get_aws_kms_client(kms_config)
         .await
         .decrypt(encrypted_key)
         .await
diff --git a/crates/router/src/routes/api_keys.rs b/crates/router/src/routes/api_keys.rs
index cf859d048dd..cf0f009a0b1 100644
--- a/crates/router/src/routes/api_keys.rs
+++ b/crates/router/src/routes/api_keys.rs
@@ -46,10 +46,10 @@ pub async fn api_key_create(
         |state, _, payload| async {
             #[cfg(feature = "aws_kms")]
             let aws_kms_client =
-                external_services::aws_kms::get_aws_kms_client(&state.clone().conf.kms).await;
+                external_services::aws_kms::core::get_aws_kms_client(&state.clone().conf.kms).await;
 
             #[cfg(feature = "hashicorp-vault")]
-            let hc_client = external_services::hashicorp_vault::get_hashicorp_client(
+            let hc_client = external_services::hashicorp_vault::core::get_hashicorp_client(
                 &state.clone().conf.hc_vault,
             )
             .await
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 651d3c0026f..84f8b62b57d 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -13,6 +13,7 @@ use external_services::email::{ses::AwsSes, EmailService};
 use external_services::file_storage::FileStorageInterface;
 #[cfg(all(feature = "olap", feature = "hashicorp-vault"))]
 use external_services::hashicorp_vault::decrypt::VaultFetch;
+use hyperswitch_interfaces::encryption_interface::EncryptionManagementInterface;
 #[cfg(all(feature = "olap", feature = "aws_kms"))]
 use masking::PeekInterface;
 use router_env::tracing_actix_web::RequestId;
@@ -73,6 +74,7 @@ pub struct AppState {
     pub pool: crate::analytics::AnalyticsProvider,
     pub request_id: Option<RequestId>,
     pub file_storage_client: Box<dyn FileStorageInterface>,
+    pub encryption_client: Box<dyn EncryptionManagementInterface>,
 }
 
 impl scheduler::SchedulerAppState for AppState {
@@ -150,13 +152,20 @@ impl AppState {
         shut_down_signal: oneshot::Sender<()>,
         api_client: Box<dyn crate::services::ApiClient>,
     ) -> Self {
+        #[allow(clippy::expect_used)]
+        let encryption_client = conf
+            .encryption_management
+            .get_encryption_management_client()
+            .await
+            .expect("Failed to create encryption client");
+
         Box::pin(async move {
             #[cfg(feature = "aws_kms")]
-            let aws_kms_client = aws_kms::get_aws_kms_client(&conf.kms).await;
+            let aws_kms_client = aws_kms::core::get_aws_kms_client(&conf.kms).await;
             #[cfg(all(feature = "hashicorp-vault", feature = "olap"))]
             #[allow(clippy::expect_used)]
             let hc_client =
-                external_services::hashicorp_vault::get_hashicorp_client(&conf.hc_vault)
+                external_services::hashicorp_vault::core::get_hashicorp_client(&conf.hc_vault)
                     .await
                     .expect("Failed while creating hashicorp_client");
             let testable = storage_impl == StorageImpl::PostgresqlTest;
@@ -204,7 +213,7 @@ impl AppState {
                     sqlx.password = sqlx
                         .password
                         .clone()
-                        .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+                        .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
                         .await
                         .expect("Failed while fetching from hashicorp vault");
                 }
@@ -230,7 +239,7 @@ impl AppState {
             {
                 conf.connector_onboarding = conf
                     .connector_onboarding
-                    .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+                    .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
                     .await
                     .expect("Failed to decrypt connector onboarding credentials");
             }
@@ -254,7 +263,7 @@ impl AppState {
                 conf.jwekey = conf
                     .jwekey
                     .clone()
-                    .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+                    .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
                     .await
                     .expect("Failed to decrypt connector onboarding credentials");
             }
@@ -287,6 +296,7 @@ impl AppState {
                 pool,
                 request_id: None,
                 file_storage_client,
+                encryption_client,
             }
         })
         .await
diff --git a/crates/router/src/services.rs b/crates/router/src/services.rs
index 220fde4631f..dc7bf14fecf 100644
--- a/crates/router/src/services.rs
+++ b/crates/router/src/services.rs
@@ -46,18 +46,19 @@ pub async fn get_store(
     test_transaction: bool,
 ) -> StorageResult<Store> {
     #[cfg(feature = "aws_kms")]
-    let aws_kms_client = aws_kms::get_aws_kms_client(&config.kms).await;
+    let aws_kms_client = aws_kms::core::get_aws_kms_client(&config.kms).await;
 
     #[cfg(feature = "hashicorp-vault")]
-    let hc_client = external_services::hashicorp_vault::get_hashicorp_client(&config.hc_vault)
-        .await
-        .change_context(StorageError::InitializationError)?;
+    let hc_client =
+        external_services::hashicorp_vault::core::get_hashicorp_client(&config.hc_vault)
+            .await
+            .change_context(StorageError::InitializationError)?;
 
     let master_config = config.master_database.clone();
 
     #[cfg(feature = "hashicorp-vault")]
     let master_config = master_config
-        .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+        .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
         .await
         .change_context(StorageError::InitializationError)
         .attach_printable("Failed to fetch data from hashicorp vault")?;
@@ -74,7 +75,7 @@ pub async fn get_store(
 
     #[cfg(all(feature = "olap", feature = "hashicorp-vault"))]
     let replica_config = replica_config
-        .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+        .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
         .await
         .change_context(StorageError::InitializationError)
         .attach_printable("Failed to fetch data from hashicorp vault")?;
@@ -128,15 +129,15 @@ pub async fn get_store(
 #[allow(clippy::expect_used)]
 async fn get_master_enc_key(
     conf: &crate::configs::settings::Settings,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::core::AwsKmsClient,
     #[cfg(feature = "hashicorp-vault")]
-    hc_client: &external_services::hashicorp_vault::HashiCorpVault,
+    hc_client: &external_services::hashicorp_vault::core::HashiCorpVault,
 ) -> StrongSecret<Vec<u8>> {
     let master_enc_key = conf.secrets.master_enc_key.clone();
 
     #[cfg(feature = "hashicorp-vault")]
     let master_enc_key = master_enc_key
-        .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+        .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
         .await
         .expect("Failed to fetch master enc key");
 
diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs
index 308ceb2672b..990e0785306 100644
--- a/crates/router/src/services/authentication.rs
+++ b/crates/router/src/services/authentication.rs
@@ -226,9 +226,9 @@ where
             api_keys::get_hash_key(
                 &config.api_keys,
                 #[cfg(feature = "aws_kms")]
-                aws_kms::get_aws_kms_client(&config.kms).await,
+                aws_kms::core::get_aws_kms_client(&config.kms).await,
                 #[cfg(feature = "hashicorp-vault")]
-                external_services::hashicorp_vault::get_hashicorp_client(&config.hc_vault)
+                external_services::hashicorp_vault::core::get_hashicorp_client(&config.hc_vault)
                     .await
                     .change_context(errors::ApiErrorResponse::InternalServerError)?,
             )
@@ -289,9 +289,9 @@ static ADMIN_API_KEY: tokio::sync::OnceCell<StrongSecret<String>> =
 
 pub async fn get_admin_api_key(
     secrets: &settings::Secrets,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::core::AwsKmsClient,
     #[cfg(feature = "hashicorp-vault")]
-    hc_client: &external_services::hashicorp_vault::HashiCorpVault,
+    hc_client: &external_services::hashicorp_vault::core::HashiCorpVault,
 ) -> RouterResult<&'static StrongSecret<String>> {
     ADMIN_API_KEY
         .get_or_try_init(|| async {
@@ -308,7 +308,7 @@ pub async fn get_admin_api_key(
 
             #[cfg(feature = "hashicorp-vault")]
             let admin_api_key = masking::Secret::new(admin_api_key)
-                .fetch_inner::<external_services::hashicorp_vault::Kv2>(hc_client)
+                .fetch_inner::<external_services::hashicorp_vault::core::Kv2>(hc_client)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed to KMS decrypt admin API key")?
@@ -369,9 +369,9 @@ where
         let admin_api_key = get_admin_api_key(
             &conf.secrets,
             #[cfg(feature = "aws_kms")]
-            aws_kms::get_aws_kms_client(&conf.kms).await,
+            aws_kms::core::get_aws_kms_client(&conf.kms).await,
             #[cfg(feature = "hashicorp-vault")]
-            external_services::hashicorp_vault::get_hashicorp_client(&conf.hc_vault)
+            external_services::hashicorp_vault::core::get_hashicorp_client(&conf.hc_vault)
                 .await
                 .change_context(errors::ApiErrorResponse::InternalServerError)
                 .attach_printable("Failed while getting admin api key")?,
@@ -873,7 +873,7 @@ static JWT_SECRET: tokio::sync::OnceCell<StrongSecret<String>> = tokio::sync::On
 
 pub async fn get_jwt_secret(
     secrets: &settings::Secrets,
-    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] aws_kms_client: &aws_kms::core::AwsKmsClient,
 ) -> RouterResult<&'static StrongSecret<String>> {
     JWT_SECRET
         .get_or_try_init(|| async {
@@ -901,7 +901,7 @@ where
     let secret = get_jwt_secret(
         &conf.secrets,
         #[cfg(feature = "aws_kms")]
-        aws_kms::get_aws_kms_client(&conf.kms).await,
+        aws_kms::core::get_aws_kms_client(&conf.kms).await,
     )
     .await?
     .peek()
@@ -972,7 +972,7 @@ static RECON_API_KEY: tokio::sync::OnceCell<StrongSecret<String>> =
 #[cfg(feature = "recon")]
 pub async fn get_recon_admin_api_key(
     secrets: &settings::Secrets,
-    #[cfg(feature = "aws_kms")] kms_client: &aws_kms::AwsKmsClient,
+    #[cfg(feature = "aws_kms")] kms_client: &aws_kms::core::AwsKmsClient,
 ) -> RouterResult<&'static StrongSecret<String>> {
     RECON_API_KEY
         .get_or_try_init(|| async {
@@ -1013,7 +1013,7 @@ where
         let admin_api_key = get_recon_admin_api_key(
             &conf.secrets,
             #[cfg(feature = "aws_kms")]
-            aws_kms::get_aws_kms_client(&conf.kms).await,
+            aws_kms::core::get_aws_kms_client(&conf.kms).await,
         )
         .await?;
 
diff --git a/crates/router/src/services/jwt.rs b/crates/router/src/services/jwt.rs
index 08db52e4020..05de1b4e11e 100644
--- a/crates/router/src/services/jwt.rs
+++ b/crates/router/src/services/jwt.rs
@@ -27,7 +27,7 @@ where
     let jwt_secret = authentication::get_jwt_secret(
         &settings.secrets,
         #[cfg(feature = "aws_kms")]
-        external_services::aws_kms::get_aws_kms_client(&settings.kms).await,
+        external_services::aws_kms::core::get_aws_kms_client(&settings.kms).await,
     )
     .await
     .change_context(UserErrors::InternalServerError)
diff --git a/crates/router/src/utils/currency.rs b/crates/router/src/utils/currency.rs
index 057805a76f0..30ac4815efb 100644
--- a/crates/router/src/utils/currency.rs
+++ b/crates/router/src/utils/currency.rs
@@ -128,9 +128,9 @@ async fn waited_fetch_and_update_caches(
     state: &AppState,
     local_fetch_retry_delay: u64,
     local_fetch_retry_count: u64,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     for _n in 1..local_fetch_retry_count {
         sleep(Duration::from_millis(local_fetch_retry_delay)).await;
@@ -192,9 +192,9 @@ pub async fn get_forex_rates(
     call_delay: i64,
     local_fetch_retry_delay: u64,
     local_fetch_retry_count: u64,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     if let Some(local_rates) = retrieve_forex_from_local().await {
         if local_rates.is_expired(call_delay) {
@@ -234,9 +234,9 @@ async fn handler_local_no_data(
     call_delay: i64,
     _local_fetch_retry_delay: u64,
     _local_fetch_retry_count: u64,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     match retrieve_forex_from_redis(state).await {
         Ok(Some(data)) => {
@@ -281,9 +281,9 @@ async fn handler_local_no_data(
 async fn successive_fetch_and_save_forex(
     state: &AppState,
     stale_redis_data: Option<FxExchangeRatesCacheEntry>,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     match acquire_redis_lock(state).await {
         Ok(lock_acquired) => {
@@ -351,9 +351,9 @@ async fn fallback_forex_redis_check(
     state: &AppState,
     redis_data: FxExchangeRatesCacheEntry,
     call_delay: i64,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     match is_redis_expired(Some(redis_data.clone()).as_ref(), call_delay).await {
         Some(redis_forex) => {
@@ -381,9 +381,9 @@ async fn handler_local_expired(
     state: &AppState,
     call_delay: i64,
     local_rates: FxExchangeRatesCacheEntry,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     match retrieve_forex_from_redis(state).await {
         Ok(redis_data) => {
@@ -427,14 +427,14 @@ async fn handler_local_expired(
 
 async fn fetch_forex_rates(
     state: &AppState,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
 
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> Result<FxExchangeRatesCacheEntry, error_stack::Report<ForexCacheError>> {
     let forex_api_key = async {
         #[cfg(feature = "hashicorp-vault")]
-        let client = hashicorp_vault::get_hashicorp_client(hc_config)
+        let client = hashicorp_vault::core::get_hashicorp_client(hc_config)
             .await
             .change_context(ForexCacheError::AwsKmsDecryptionFailed)?;
 
@@ -446,7 +446,7 @@ async fn fetch_forex_rates(
             .forex_api
             .api_key
             .clone()
-            .fetch_inner::<hashicorp_vault::Kv2>(client)
+            .fetch_inner::<hashicorp_vault::core::Kv2>(client)
             .await
             .change_context(ForexCacheError::AwsKmsDecryptionFailed)?;
 
@@ -454,7 +454,7 @@ async fn fetch_forex_rates(
     }
     .await?;
     #[cfg(feature = "aws_kms")]
-    let forex_api_key = aws_kms::get_aws_kms_client(aws_kms_config)
+    let forex_api_key = aws_kms::core::get_aws_kms_client(aws_kms_config)
         .await
         .decrypt(forex_api_key.peek())
         .await
@@ -516,13 +516,13 @@ async fn fetch_forex_rates(
 
 pub async fn fallback_fetch_forex_rates(
     state: &AppState,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<FxExchangeRatesCacheEntry, ForexCacheError> {
     let fallback_api_key = async {
         #[cfg(feature = "hashicorp-vault")]
-        let client = hashicorp_vault::get_hashicorp_client(hc_config)
+        let client = hashicorp_vault::core::get_hashicorp_client(hc_config)
             .await
             .change_context(ForexCacheError::AwsKmsDecryptionFailed)?;
 
@@ -534,7 +534,7 @@ pub async fn fallback_fetch_forex_rates(
             .forex_api
             .fallback_api_key
             .clone()
-            .fetch_inner::<hashicorp_vault::Kv2>(client)
+            .fetch_inner::<hashicorp_vault::core::Kv2>(client)
             .await
             .change_context(ForexCacheError::AwsKmsDecryptionFailed)?;
 
@@ -542,7 +542,7 @@ pub async fn fallback_fetch_forex_rates(
     }
     .await?;
     #[cfg(feature = "aws_kms")]
-    let fallback_forex_api_key = aws_kms::get_aws_kms_client(aws_kms_config)
+    let fallback_forex_api_key = aws_kms::core::get_aws_kms_client(aws_kms_config)
         .await
         .decrypt(fallback_api_key.peek())
         .await
@@ -691,9 +691,9 @@ pub async fn convert_currency(
     amount: i64,
     to_currency: String,
     from_currency: String,
-    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::AwsKmsConfig,
+    #[cfg(feature = "aws_kms")] aws_kms_config: &aws_kms::core::AwsKmsConfig,
     #[cfg(feature = "hashicorp-vault")]
-    hc_config: &external_services::hashicorp_vault::HashiCorpVaultConfig,
+    hc_config: &external_services::hashicorp_vault::core::HashiCorpVaultConfig,
 ) -> CustomResult<api_models::currency::CurrencyConversionResponse, ForexCacheError> {
     let rates = get_forex_rates(
         &state,