deepstrike_sdk/runtime/
credential_vault.rs1use async_trait::async_trait;
2use std::collections::HashMap;
3use std::sync::Arc;
4use tokio::sync::RwLock;
5
6#[async_trait]
8pub trait CredentialVault: Send + Sync {
9 async fn get(&self, key: &str) -> Option<String>;
10}
11
12pub struct EnvCredentialVault;
14
15#[async_trait]
16impl CredentialVault for EnvCredentialVault {
17 async fn get(&self, key: &str) -> Option<String> {
18 std::env::var(key).ok()
19 }
20}
21
22pub struct InMemoryCredentialVault {
24 store: Arc<RwLock<HashMap<String, String>>>,
25}
26
27impl Default for InMemoryCredentialVault {
28 fn default() -> Self {
29 Self {
30 store: Arc::new(RwLock::new(HashMap::new())),
31 }
32 }
33}
34
35impl InMemoryCredentialVault {
36 pub fn new() -> Self {
37 Self::default()
38 }
39
40 pub async fn set(&self, key: impl Into<String>, value: impl Into<String>) {
41 self.store.write().await.insert(key.into(), value.into());
42 }
43}
44
45#[async_trait]
46impl CredentialVault for InMemoryCredentialVault {
47 async fn get(&self, key: &str) -> Option<String> {
48 self.store.read().await.get(key).cloned()
49 }
50}
51
52pub struct ChainedCredentialVault {
54 vaults: Vec<Box<dyn CredentialVault>>,
55}
56
57impl ChainedCredentialVault {
58 pub fn new(vaults: Vec<Box<dyn CredentialVault>>) -> Self {
59 Self { vaults }
60 }
61}
62
63#[async_trait]
64impl CredentialVault for ChainedCredentialVault {
65 async fn get(&self, key: &str) -> Option<String> {
66 for vault in &self.vaults {
67 if let Some(v) = vault.get(key).await {
68 return Some(v);
69 }
70 }
71 None
72 }
73}