-
Notifications
You must be signed in to change notification settings - Fork 13
feat(engine): implement hashicorp vault engine #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akhildevelops Please mention me once the comments are resolved and encryption/decryption part is implemented for Data encryption
docker-compose.yml
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are creating a docker-compose
file we need to create a fully fledged one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/config.rs
Outdated
{ | ||
// This function doesn't return result therefore unwrapping. | ||
// TODO: Make it customresult return type | ||
let client = init_vault(self.vault_config, self.vault_token).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The panic part can happen inside the init_vault
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see there are many expect methods used through out the code that can also panic. Rewired unwrap to expect.
src/errors/app.rs
Outdated
InternalServerError(&'static str), | ||
#[error("Internal Server Error Occurred - {prefix} {}",message.as_ref().unwrap_or(&"".to_string()))] | ||
InternalServerError { | ||
prefix: &'static str, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is prefix here? I think we can just use message
alone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I observe there are many static lifetime strings used for error messages. I can simply transform it to String type but every time memory will be allocated while creating error messages at different code points.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just use the message?
Cool, @dracarys18 will ping you oince changes are implemented. |
Hi @dracarys18, I'm done with my changes and also fixes #30 I might not be very active for next couple of days. I'll try to respond for any comments as and when I'm free. |
Setup vault, postgres and run migrations through
Run server with vault as backend through |
@akhildevelops Hey why do we need changes in CI? |
This PR fails with current ci configuration for ➜ hyperswitch-encryption-service git:(vault) cargo hack check --all-features --all-targets
info: running `cargo check --all-features --all-targets` on cripta (1/1)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
error[E0428]: the name `KeyManagerClient` is defined multiple times
--> src/crypto.rs:143:1
|
140 | pub type KeyManagerClient = EncryptionClient<AwsKmsClient>;
| ----------------------------------------------------------- previous definition of the type `KeyManagerClient` here
...
143 | pub type KeyManagerClient = EncryptionClient<GcmAes256>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `KeyManagerClient` redefined here
|
= note: `KeyManagerClient` must be defined only once in the type namespace of this module As it will open up for all features #[cfg(feature = "aws")]
pub type KeyManagerClient = EncryptionClient<AwsKmsClient>;
#[cfg(feature = "aes")]
pub type KeyManagerClient = EncryptionClient<GcmAes256>;
#[cfg(feature = "vault")]
pub type KeyManagerClient = EncryptionClient<Vault>; It isn't a problem in the current main:63c6794 because of simple aws or !aws. |
@akhildevelops You can try something like conditional compilation #[cfg(all(feature = "aws", not(feature = "aes")))]
pub type KeyManagerClient = EncryptionClient<AwsKmsClient>; |
This will be bloated as and when multiple backends are added
|
Really don't wanna do dynamic dispatch but we can do this for readability. Change the current type Backend = dyn KeyManagement + Send + Sync;
pub struct KeyManagerClient {
client: Arc<Backend>,
}
impl KeyManagerClient {
pub fn new(client: Arc<Backend>) -> Self {
Self { client }
}
}
impl KeyManagerClient {
pub fn client(&self) -> &Arc<Backend> {
&self.client
}
}
impl Deref for KeyManagerClient {
type Target = Arc<Backend>;
fn deref(&self) -> &Self::Target {
self.client()
}
} and this in impl Secrets {
pub async fn create_keymanager_client(self) -> KeyManagerClient {
#[cfg(feature = "aws")]
{
let client = AwsKmsClient::new(&self.kms_config).await;
EncryptionClient::new(client)
}
#[cfg(not(feature = "aws"))]
{
let client = self.master_key;
KeyManagerClient::new(std::sync::Arc::new(client))
}
}
} |
Hey @akhildevelops Kindly make the changes so that the PR can be merged within time. |
Even with Dynamic trait objects how can the application decide to choose between vault or aes ? if // Is activated for both vault and aes
// Will not work if vault is the backend
#[cfg(not(feature = "aws"))]
{
let client = self.master_key;
KeyManagerClient::new(std::sync::Arc::new(client))
} I would ask you to check the ci.yml that doesn't have any harcoded way to run compilation checks for different backends. Below is the cargo hack command runs checks for each individual backend and every compilation check is successful ➜ hyperswitch-encryption-service git:(vault) cargo hack check --each-feature --exclude-no-default-features --exclude-all-features --exclude-features mtls --all-targets
info: running `cargo check --all-targets --no-default-features --features aes` on cripta (1/5)
Checking cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.78s
info: running `cargo check --all-targets --no-default-features --features aws` on cripta (2/5)
Checking cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.91s
info: running `cargo check --all-targets --no-default-features --features default` on cripta (3/5)
Checking cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.33s
info: running `cargo check --all-targets --no-default-features --features release` on cripta (4/5)
Checking cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.91s
info: running `cargo check --all-targets --no-default-features --features vault` on cripta (5/5)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
###########################
➜ hyperswitch-encryption-service git:(vault) cargo hack clippy --each-feature --exclude-no-default-features --exclude-all-features --exclude-features mtls --all-targets
info: running `cargo clippy --all-targets --no-default-features --features aes` on cripta (1/5)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.09s
info: running `cargo clippy --all-targets --no-default-features --features aws` on cripta (2/5)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.82s
info: running `cargo clippy --all-targets --no-default-features --features default` on cripta (3/5)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.81s
info: running `cargo clippy --all-targets --no-default-features --features release` on cripta (4/5)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.18s
info: running `cargo clippy --all-targets --no-default-features --features vault` on cripta (5/5)
Compiling cripta v0.1.0 (/home/akhil/practice/hyperswitch-encryption-service)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 3.77s |
With dynamic dispatch we don't have to write that line anymore. @akhildevelops If you are not able to do the change let me know I will do it |
@dracarys18 please go ahead |
Hi @akhildevelops I have made the changes I will thoroughly test this once and merge this PR! Thanks a lot for the contribution!! |
@dracarys18 Thanks for the appreciation!! If I'm correct, you're trying to avoid compilation complexities by including all features and choose feature during runtime. I have a suggestions, please discard if it doesn't help or you're ok with current design:
This pattern helps to run any backend without recompilation considering current design of trait objects. |
@akhildevelops So once you compile for AWS it doesn't make sense to switch to vault at runtime, Because all the keys would be encrypted with AWS, That's why I kept it separate. |
I have removed the README.md changes since we will add another SETUP.md to add the documentation for the setup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR looks good to me! Thanks for the PR @akhildevelops , great work!
src/config.rs
Outdated
None, | ||
) | ||
.await | ||
.expect("Failed why decrypted vault encrypted secret") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Failed while decrypting vault encrypted secret"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This PR provides support to connect to Hashicorp Vault as backend.
Features:
aes, aws, vault
.P.S:
cargo run
will fail as feature flags aren't provided. Instead run with eithercargo run --features=<aes/aws/vault>
Fixes: juspay/hyperswitch#6226