Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions cert-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use anyhow::{bail, Context, Result};
use dstack_kms_rpc::{kms_client::KmsClient, SignCertRequest};
use dstack_types::{AppKeys, KeyProvider};
use dstack_types::{AppKeys, KeyProvider, SysConfig};
use ra_rpc::client::{CertInfo, RaClient, RaClientConfig};
use ra_tls::cert::{generate_ra_cert, CaCert, CertSigningRequestV2};

Expand Down Expand Up @@ -41,6 +41,7 @@ pub enum CertRequestClient {
Kms {
client: KmsClient<RaClient>,
vm_config: String,
launch_ticket: String,
},
}

Expand All @@ -57,13 +58,18 @@ impl CertRequestClient {
.context("Failed to sign certificate")?;
Ok(vec![cert.pem(), ca.pem_cert.clone()])
}
CertRequestClient::Kms { client, vm_config } => {
CertRequestClient::Kms {
client,
vm_config,
launch_ticket,
} => {
let response = client
.sign_cert(SignCertRequest {
api_version: 2,
csr: csr.to_vec(),
signature: signature.to_vec(),
vm_config: vm_config.clone(),
launch_ticket: launch_ticket.clone(),
})
.await?;
Ok(response.certificate_chain)
Expand All @@ -81,7 +87,7 @@ impl CertRequestClient {
pub async fn create(
keys: &AppKeys,
pccs_url: Option<&str>,
vm_config: String,
sys_config: &SysConfig,
) -> Result<CertRequestClient> {
match &keys.key_provider {
KeyProvider::None { key }
Expand Down Expand Up @@ -114,7 +120,11 @@ impl CertRequestClient {
.into_client()
.context("Failed to create RA client")?;
let client = KmsClient::new(ra_client);
Ok(CertRequestClient::Kms { client, vm_config })
Ok(CertRequestClient::Kms {
client,
vm_config: sys_config.vm_config.clone(),
launch_ticket: sys_config.launch_ticket.clone().unwrap_or_default(),
})
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions dstack-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ pub struct SysConfig {
pub pccs_url: Option<String>,
pub docker_registry: Option<String>,
pub host_api_url: Option<String>,
/// Launch ticket the guest presents to the KMS, which checks its hash
/// against the app's on-chain allowlist before releasing keys. A secret
/// the host holds: unlike `vm_config`, it is never embedded in an
/// attestation or returned by the guest agent.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub launch_ticket: Option<String>,
// JSON serialized VmConfig
pub vm_config: String,
}
Expand Down
3 changes: 2 additions & 1 deletion dstack-util/src/system_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ impl HostShared {
vm_config: self.sys_config.vm_config.clone(),
root_epoch: epochs.map(|(root, _)| root),
app_epoch: epochs.map(|(_, app)| app),
launch_ticket: self.sys_config.launch_ticket.clone().unwrap_or_default(),
})
.await
.context("Failed to get app key")?;
Expand Down Expand Up @@ -749,7 +750,7 @@ impl<'a> GatewayContext<'a> {
let cert_client = CertRequestClient::create(
self.keys,
self.shared.sys_config.pccs_url.as_deref(),
self.shared.sys_config.vm_config.clone(),
&self.shared.sys_config,
)
.await
.context("Failed to create cert client")?;
Expand Down
1 change: 1 addition & 0 deletions gateway/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ async fn gen_debug_certs(
csr: csr.to_vec(),
signature,
vm_config: vm_config_json.to_string(),
..Default::default()
})
.await
.context("Failed to sign certificate via KMS")?;
Expand Down
10 changes: 5 additions & 5 deletions guest-agent/src/rpc_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,10 @@ impl AppState {
let sys_config: SysConfig =
serde_json::from_str(&fs::read_to_string(&config.sys_config_file)?)
.context("Failed to parse VM config")?;
let cert_client = CertRequestClient::create(&keys, config.pccs_url.as_deref(), &sys_config)
.await
.context("Failed to create cert signer")?;
let vm_config = sys_config.vm_config;
let cert_client =
CertRequestClient::create(&keys, config.pccs_url.as_deref(), vm_config.clone())
.await
.context("Failed to create cert signer")?;
let me = Self {
inner: Arc::new(AppStateInner {
config,
Expand Down Expand Up @@ -922,7 +921,8 @@ pNs85uhOZE8z2jr8Pg==
},
};

let dummy_cert_client = CertRequestClient::create(&dummy_keys, None, String::new())
let sys_config = serde_json::from_value(serde_json::json!({ "vm_config": "" })).unwrap();
let dummy_cert_client = CertRequestClient::create(&dummy_keys, None, &sys_config)
.await
.expect("Failed to create CertRequestClient");

Expand Down
5 changes: 5 additions & 0 deletions kms/rpc/proto/kms_rpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ message GetAppKeyRequest {
// the original root keys. Older epochs remain available so CVMs can migrate.
optional uint32 root_epoch = 3;
optional uint32 app_epoch = 4;
// The launch ticket from the CVM's sys-config; empty when it has none. Its
// hash is checked against the app's allowlist.
string launch_ticket = 5;
}

message AppId {
Expand Down Expand Up @@ -94,6 +97,8 @@ message SignCertRequest {
bytes csr = 2;
bytes signature = 3;
string vm_config = 4;
// As in GetAppKeyRequest.
string launch_ticket = 5;
}

message SignCertResponse {
Expand Down
Loading