agent_vault/core/
paths.rs1use std::path::{Path, PathBuf};
2
3pub struct VaultPaths {
5 root: PathBuf,
7}
8
9impl VaultPaths {
10 pub fn new(root: impl Into<PathBuf>) -> Self {
11 Self { root: root.into() }
12 }
13
14 pub fn vault_dir(&self) -> PathBuf {
16 self.root.join(".agent-vault")
17 }
18
19 pub fn config_file(&self) -> PathBuf {
21 self.vault_dir().join("config.yaml")
22 }
23
24 pub fn owner_pub_file(&self) -> PathBuf {
26 self.vault_dir().join("owner.pub")
27 }
28
29 pub fn manifest_file(&self) -> PathBuf {
31 self.vault_dir().join("manifest.yaml")
32 }
33
34 pub fn gitignore_file(&self) -> PathBuf {
36 self.vault_dir().join(".gitignore")
37 }
38
39 pub fn agents_dir(&self) -> PathBuf {
41 self.vault_dir().join("agents")
42 }
43
44 pub fn agent_dir(&self, name: &str) -> PathBuf {
46 self.agents_dir().join(name)
47 }
48
49 pub fn agent_pub_file(&self, name: &str) -> PathBuf {
51 self.agent_dir(name).join("public.key")
52 }
53
54 pub fn agent_escrow_file(&self, name: &str) -> PathBuf {
56 self.agent_dir(name).join("private.key.escrow")
57 }
58
59 pub fn secrets_dir(&self) -> PathBuf {
61 self.vault_dir().join("secrets")
62 }
63
64 pub fn secret_enc_file(&self, path: &str) -> PathBuf {
66 let (group, name) = split_secret_path(path);
67 self.secrets_dir().join(group).join(format!("{name}.enc"))
68 }
69
70 pub fn secret_meta_file(&self, path: &str) -> PathBuf {
72 let (group, name) = split_secret_path(path);
73 self.secrets_dir().join(group).join(format!("{name}.meta"))
74 }
75
76 pub fn root(&self) -> &Path {
77 &self.root
78 }
79}
80
81pub fn owner_key_path() -> PathBuf {
83 home_vault_dir().join("owner.key")
84}
85
86pub fn agent_key_path(name: &str) -> PathBuf {
88 home_vault_dir().join("agents").join(format!("{name}.key"))
89}
90
91pub fn home_vault_dir() -> PathBuf {
93 dirs::home_dir()
94 .expect("could not determine home directory")
95 .join(".agent-vault")
96}
97
98fn split_secret_path(path: &str) -> (&str, &str) {
101 match path.split_once('/') {
102 Some((group, name)) => (group, name),
103 None => ("default", path),
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_split_secret_path() {
113 assert_eq!(split_secret_path("stripe/api-key"), ("stripe", "api-key"));
114 assert_eq!(split_secret_path("my-secret"), ("default", "my-secret"));
115 }
116
117 #[test]
118 fn test_vault_paths() {
119 let paths = VaultPaths::new("/tmp/repo");
120 assert_eq!(paths.vault_dir(), PathBuf::from("/tmp/repo/.agent-vault"));
121 assert_eq!(
122 paths.secret_enc_file("stripe/api-key"),
123 PathBuf::from("/tmp/repo/.agent-vault/secrets/stripe/api-key.enc")
124 );
125 }
126}