1use std::path::{Path, PathBuf};
2
3const DEFAULT_AGENT_ID: &str = "default-agent";
4const AGENTS_DIR_NAME: &str = "agents";
5const AGE_KEY_FILE_NAME: &str = "age.key";
6const SIGNING_KEY_FILE_NAME: &str = "signing.key";
7const GPG_DIR_NAME: &str = "gpg";
8
9#[derive(Debug, Clone)]
11pub struct SecretsPaths {
12 root: PathBuf,
13}
14
15impl SecretsPaths {
16 pub fn new(root: impl AsRef<Path>) -> Self {
18 Self {
19 root: root.as_ref().to_path_buf(),
20 }
21 }
22
23 pub fn root(&self) -> &Path {
25 &self.root
26 }
27
28 pub fn store_dir(&self) -> PathBuf {
30 self.root.join("store")
31 }
32
33 pub fn metadata_dir(&self) -> PathBuf {
35 self.root.join("meta")
36 }
37
38 pub fn pending_file(&self) -> PathBuf {
40 self.root.join("pending.json")
41 }
42
43 pub fn audit_file(&self) -> PathBuf {
45 self.root.join("audit.jsonl")
46 }
47
48 pub fn default_identity_file(&self) -> PathBuf {
50 self.identity_file_for_agent(DEFAULT_AGENT_ID)
51 }
52
53 pub fn agents_dir(&self) -> PathBuf {
55 self.root.join(AGENTS_DIR_NAME)
56 }
57
58 pub fn agent_dir(&self, agent_id: &str) -> PathBuf {
60 self.agents_dir().join(agent_id)
61 }
62
63 pub fn identity_file_for_agent(&self, agent_id: &str) -> PathBuf {
65 self.agent_dir(agent_id).join(AGE_KEY_FILE_NAME)
66 }
67
68 pub fn legacy_identity_file_for_agent(&self, agent_id: &str) -> PathBuf {
70 self.root.join(format!("{agent_id}.agekey"))
71 }
72
73 pub fn namespaced_identity_file_for_agent(&self, agent_id: &str) -> PathBuf {
75 self.root.join("identities").join(format!("{agent_id}.age"))
76 }
77
78 pub fn default_signing_key_file(&self) -> PathBuf {
80 self.signing_key_file_for_agent(DEFAULT_AGENT_ID)
81 }
82
83 pub fn signing_key_file_for_agent(&self, agent_id: &str) -> PathBuf {
85 self.agent_dir(agent_id).join(SIGNING_KEY_FILE_NAME)
86 }
87
88 pub fn legacy_signing_key_file_for_agent(&self, agent_id: &str) -> PathBuf {
90 self.root.join(format!("{agent_id}.signing.key"))
91 }
92
93 pub fn vaults_dir(&self) -> PathBuf {
95 self.root.join("vaults")
96 }
97
98 pub fn gpg_homes_dir(&self) -> PathBuf {
100 self.agents_dir()
101 }
102
103 pub fn gpg_home(&self, agent_id: &str) -> PathBuf {
105 self.agent_dir(agent_id).join(GPG_DIR_NAME)
106 }
107
108 pub fn legacy_gpg_home(&self, agent_id: &str) -> PathBuf {
110 self.root.join(GPG_DIR_NAME).join(agent_id)
111 }
112
113 pub fn vault_sessions_file(&self) -> PathBuf {
115 self.vaults_dir().join("sessions.json")
116 }
117
118 pub fn encrypted_dir(&self) -> PathBuf {
120 self.root.join("encrypted")
121 }
122
123 pub fn mounts_dir(&self) -> PathBuf {
125 self.root.join("mnt")
126 }
127
128 pub fn vault_config_file(&self, vault_name: &str) -> PathBuf {
130 self.vaults_dir().join(format!("{vault_name}.toml"))
131 }
132
133 pub fn vault_cipher_dir(&self, vault_name: &str) -> PathBuf {
135 self.encrypted_dir().join(vault_name)
136 }
137
138 pub fn vault_mountpoint(&self, vault_name: &str) -> PathBuf {
140 self.mounts_dir().join(vault_name)
141 }
142}