Skip to content

Commit

Permalink
KBS: add aliyun KMS backend support for KBS storage
Browse files Browse the repository at this point in the history
Signed-off-by: Xynnn007 <[email protected]>
  • Loading branch information
Xynnn007 committed Jul 20, 2024
1 parent d8858be commit 104c878
Show file tree
Hide file tree
Showing 8 changed files with 444 additions and 47 deletions.
402 changes: 363 additions & 39 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sha2 = "0.10"
shadow-rs = "0.19.0"
strum = { version = "0.25", features = ["derive"] }
thiserror = "1.0"
tokio = { version = "1.23.0", features = ["full"] }
tokio = { version = "1", features = ["full"] }
tempfile = "3.4.0"
tonic = "0.11"
tonic-build = "0.11"
4 changes: 4 additions & 0 deletions kbs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ rustls = ["actix-web/rustls", "dep:rustls", "dep:rustls-pemfile"]
# Use openssl crypto stack for KBS
openssl = ["actix-web/openssl", "dep:openssl"]

# Use aliyun KMS as KBS backend
aliyun = ["kms/aliyun"]

[dependencies]
actix-web.workspace = true
actix-web-httpauth.workspace = true
Expand All @@ -57,6 +60,7 @@ env_logger.workspace = true
jsonwebtoken = { workspace = true, default-features = false, optional = true }
jwt-simple.workspace = true
kbs-types.workspace = true
kms = { git = "https://github.com/Xynnn007/guest-components.git", rev="e6bcb31", default-features = false }
lazy_static = "1.4.0"
log.workspace = true
mobc = { version = "0.8.3", optional = true }
Expand Down
4 changes: 2 additions & 2 deletions kbs/src/http/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ pub(crate) async fn get_resource(
}

let resource_byte = repository
.read()
.write()
.await
.read_secret_resource(resource_description)
.await
.map_err(|e| Error::ReadSecretFailed(e.to_string()))?;
.map_err(|e| Error::ReadSecretFailed(format!("{e:?}")))?;

let jwe = jwe(pubkey, resource_byte)?;

Expand Down
59 changes: 59 additions & 0 deletions kbs/src/resource/aliyun_kms.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2024 by Alibaba.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

use super::{Repository, ResourceDesc};
use anyhow::{Context, Result};
use kms::{plugins::aliyun::AliyunKmsClient, Annotations, Getter};
use log::info;
use serde::Deserialize;

#[derive(Debug, Deserialize, Clone)]
pub struct AliyunKmsBackendConfig {
client_key: String,
kms_instance_id: String,
password: String,
cert_pem: String,
}

pub struct AliyunKmsBackend {
client: AliyunKmsClient,
}

#[async_trait::async_trait]
impl Repository for AliyunKmsBackend {
async fn read_secret_resource(&mut self, resource_desc: ResourceDesc) -> Result<Vec<u8>> {
info!(
"Use aliyun KMS backend. Ignore {}/{}",
resource_desc.repository_name, resource_desc.resource_type
);
let name = resource_desc.resource_tag;
let resource_byte = self
.client
.get_secret(&name, &Annotations::default())
.await
.context("failed to get resource from aliyun KMS")?;
Ok(resource_byte)
}

async fn write_secret_resource(
&mut self,
_resource_desc: ResourceDesc,
_data: &[u8],
) -> Result<()> {
todo!("Does not support!")
}
}

impl AliyunKmsBackend {
pub fn new(repo_desc: &AliyunKmsBackendConfig) -> Result<Self> {
let client = AliyunKmsClient::new(
&repo_desc.client_key,
&repo_desc.kms_instance_id,
&repo_desc.password,
&repo_desc.cert_pem,
)
.context("create aliyun KMS backend")?;
Ok(Self { client })
}
}
2 changes: 1 addition & 1 deletion kbs/src/resource/local_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct LocalFs {

#[async_trait::async_trait]
impl Repository for LocalFs {
async fn read_secret_resource(&self, resource_desc: ResourceDesc) -> Result<Vec<u8>> {
async fn read_secret_resource(&mut self, resource_desc: ResourceDesc) -> Result<Vec<u8>> {
let mut resource_path = PathBuf::from(&self.repo_dir_path);

let ref_resource_path = format!(
Expand Down
16 changes: 13 additions & 3 deletions kbs/src/resource/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ use serde::Deserialize;
use std::fs;
use std::path::Path;
use std::sync::Arc;
use strum::EnumString;
use tokio::sync::RwLock;

mod local_fs;

#[cfg(feature = "aliyun")]
mod aliyun_kms;

/// Interface of a `Repository`.
#[async_trait::async_trait]
pub trait Repository {
/// Read secret resource from repository.
async fn read_secret_resource(&self, resource_desc: ResourceDesc) -> Result<Vec<u8>>;
async fn read_secret_resource(&mut self, resource_desc: ResourceDesc) -> Result<Vec<u8>>;

/// Write secret resource into repository
async fn write_secret_resource(
Expand Down Expand Up @@ -46,10 +48,13 @@ impl ResourceDesc {
}
}

#[derive(Clone, Debug, Deserialize, EnumString)]
#[derive(Clone, Debug, Deserialize)]
#[serde(tag = "type")]
pub enum RepositoryConfig {
LocalFs(local_fs::LocalFsRepoDesc),

#[cfg(feature = "aliyun")]
Aliyun(aliyun_kms::AliyunKmsBackendConfig),
}

impl RepositoryConfig {
Expand All @@ -73,6 +78,11 @@ impl RepositoryConfig {
Ok(Arc::new(RwLock::new(local_fs::LocalFs::new(desc)?))
as Arc<RwLock<dyn Repository + Send + Sync>>)
}
#[cfg(feature = "aliyun")]
Self::Aliyun(config) => {
let client = aliyun_kms::AliyunKmsBackend::new(config)?;
Ok(Arc::new(RwLock::new(client)) as Arc<RwLock<dyn Repository + Send + Sync>>)
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tools/kbs-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ base64.workspace = true
clap = { version = "4.0.29", features = ["derive"] }
env_logger.workspace = true
jwt-simple.workspace = true
kbs_protocol = { git = "https://github.com/confidential-containers/guest-components.git", rev="df60725afe0ba452a25a740cf460c2855442c49a", default-features = false }
kbs_protocol = { git = "https://github.com/Xynnn007/guest-components.git", rev="e6bcb31", default-features = false }
log.workspace = true
reqwest = { workspace = true, default-features = false, features = ["cookies", "json"] }
serde = { workspace = true, features = ["derive"] }
Expand Down

0 comments on commit 104c878

Please sign in to comment.