agent: support sealed secret as env in kata

Fixes: #7555

Signed-off-by: Linda Yu <linda.yu@intel.com>
This commit is contained in:
Linda Yu 2023-08-07 19:07:03 +08:00 committed by Biao Lu
parent 5316839165
commit 75def881e5
5 changed files with 100 additions and 3 deletions

1
src/agent/Cargo.lock generated
View File

@ -2124,6 +2124,7 @@ dependencies = [
"cgroups-rs",
"clap",
"const_format",
"derivative",
"futures",
"image-rs",
"ipnetwork",

View File

@ -25,6 +25,7 @@ kata-sys-util = { path = "../libs/kata-sys-util" }
kata-types = { path = "../libs/kata-types" }
const_format = "0.2.30"
url = "2.2.2"
derivative = "2.2.0"
# Async helpers
async-trait = "0.1.42"

66
src/agent/src/cdh.rs Normal file
View File

@ -0,0 +1,66 @@
// Copyright (c) 2023 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
// Confidential Data Hub client wrapper.
// Confidential Data Hub is a service running inside guest to provide resource related APIs.
// https://github.com/confidential-containers/guest-components/tree/main/confidential-data-hub
use anyhow::{anyhow, Result};
use protocols::{
sealed_secret, sealed_secret_ttrpc_async, sealed_secret_ttrpc_async::SealedSecretServiceClient,
};
const CDH_ADDR: &str = "unix:///run/confidential-containers/cdh.sock";
#[derive(Clone)]
pub struct CDHClient {
sealed_secret_client: SealedSecretServiceClient,
}
impl CDHClient {
pub fn new() -> Result<Self> {
let c = ttrpc::asynchronous::Client::connect(CDH_ADDR)?;
let ssclient = sealed_secret_ttrpc_async::SealedSecretServiceClient::new(c);
Ok(CDHClient {
sealed_secret_client: ssclient,
})
}
pub async fn unseal_secret_async(
&self,
sealed: &str,
) -> Result<sealed_secret::UnsealSecretOutput> {
let secret = sealed
.strip_prefix("sealed.")
.ok_or(anyhow!("strip_prefix sealed. failed"))?;
let mut input = sealed_secret::UnsealSecretInput::new();
input.set_secret(secret.into());
let unseal = self
.sealed_secret_client
.unseal_secret(
ttrpc::context::with_timeout(50 * 1000 * 1000 * 1000),
&input,
)
.await?;
Ok(unseal)
}
pub async fn unseal_env(&self, env: &str) -> Result<String> {
let (key, value) = env.split_once('=').unwrap();
if value.starts_with("sealed.") {
let unsealed_value = self.unseal_secret_async(value).await;
match unsealed_value {
Ok(v) => {
let plain_env =
format!("{}={}", key, std::str::from_utf8(&v.plaintext).unwrap());
return Ok(plain_env);
}
Err(e) => {
return Err(e);
}
};
}
Ok((*env.to_owned()).to_string())
}
}

View File

@ -37,6 +37,8 @@ use std::process::Command;
use std::sync::Arc;
use tracing::{instrument, span};
#[cfg(feature = "confidential-data-hub")]
mod cdh;
mod config;
mod console;
mod device;

View File

@ -71,6 +71,7 @@ use crate::AGENT_CONFIG;
use crate::trace_rpc_call;
use crate::tracer::extract_carrier_from_ttrpc;
use derivative::Derivative;
use opentelemetry::global;
use tracing::span;
use tracing_opentelemetry::OpenTelemetrySpanExt;
@ -89,6 +90,9 @@ use std::io::{BufRead, BufReader, Write};
use std::os::unix::fs::FileExt;
use std::path::PathBuf;
#[cfg(feature = "sealed-secret")]
use crate::cdh::CDHClient;
pub const CONTAINER_BASE: &str = "/run/kata-containers";
const MODPROBE_PATH: &str = "/sbin/modprobe";
const CONFIG_JSON: &str = "config.json";
@ -139,10 +143,14 @@ fn is_allowed(req: &impl MessageDyn) -> ttrpc::Result<()> {
}
}
#[derive(Clone, Debug)]
#[derive(Derivative)]
#[derivative(Clone, Debug)]
pub struct AgentService {
sandbox: Arc<Mutex<Sandbox>>,
init_mode: bool,
#[derivative(Debug = "ignore")]
#[cfg(feature = "sealed-secret")]
cdh_client: Option<CDHClient>,
}
// A container ID must match this regex:
@ -201,6 +209,25 @@ impl AgentService {
// cannot predict everything from the caller.
add_devices(&req.devices, &mut oci, &self.sandbox).await?;
if cfg!(feature = "sealed-secret") {
let process = oci
.process
.as_mut()
.ok_or_else(|| anyhow!("Spec didn't contain process field"))?;
for env in process.env.iter_mut() {
let client = self
.cdh_client
.as_ref()
.ok_or(anyhow!("get cdh_client failed"))?;
let unsealed_env = client
.unseal_env(env)
.await
.map_err(|e| anyhow!("unseal env failed: {:?}", e))?;
*env = unsealed_env.to_string();
}
}
let linux = oci
.linux
.as_mut()
@ -1697,6 +1724,8 @@ pub async fn start(
let agent_service = Box::new(AgentService {
sandbox: s.clone(),
init_mode,
#[cfg(feature = "sealed-secret")]
cdh_client: Some(CDHClient::new()?),
}) as Box<dyn agent_ttrpc::AgentService + Send + Sync>;
let aservice = agent_ttrpc::create_agent_service(Arc::new(agent_service));
@ -2226,7 +2255,6 @@ mod tests {
async fn test_update_routes() {
let logger = slog::Logger::root(slog::Discard, o!());
let sandbox = Sandbox::new(&logger).unwrap();
let agent_service = Box::new(AgentService {
sandbox: Arc::new(Mutex::new(sandbox)),
init_mode: true,
@ -2244,7 +2272,6 @@ mod tests {
async fn test_add_arp_neighbors() {
let logger = slog::Logger::root(slog::Discard, o!());
let sandbox = Sandbox::new(&logger).unwrap();
let agent_service = Box::new(AgentService {
sandbox: Arc::new(Mutex::new(sandbox)),
init_mode: true,