use std::sync::Mutex;
use vti_common::error::AppError;
use super::{BoxFuture, SeedStore};
pub struct KmsTeeSeedStore {
seed: Mutex<Option<Vec<u8>>>,
_key_arn: String,
_region: String,
}
impl KmsTeeSeedStore {
pub fn new(seed: Vec<u8>, key_arn: String, region: String) -> Self {
Self {
seed: Mutex::new(Some(seed)),
_key_arn: key_arn,
_region: region,
}
}
}
impl SeedStore for KmsTeeSeedStore {
fn get(&self) -> BoxFuture<'_, Result<Option<Vec<u8>>, AppError>> {
Box::pin(async {
let guard = self
.seed
.lock()
.map_err(|e| AppError::SecretStore(format!("seed lock poisoned: {e}")))?;
Ok(guard.clone())
})
}
fn set(&self, seed: &[u8]) -> BoxFuture<'_, Result<(), AppError>> {
let seed = seed.to_vec();
Box::pin(async move {
tracing::warn!(
"KmsTeeSeedStore::set updates the in-memory seed only — it is \
NOT persisted and will be lost on the next enclave boot"
);
let mut guard = self
.seed
.lock()
.map_err(|e| AppError::SecretStore(format!("seed lock poisoned: {e}")))?;
*guard = Some(seed);
Ok(())
})
}
fn set_persists_across_restart(&self) -> bool {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn set_does_not_persist_across_restart() {
let store =
KmsTeeSeedStore::new(vec![0u8; 32], "arn:aws:kms:test".into(), "us-east-1".into());
assert!(
!store.set_persists_across_restart(),
"the TEE KMS seed store must report that set() is not restart-durable \
so the rotation path refuses"
);
}
}