1#![deny(missing_docs)]
2pub mod lockbox {
15 pub use revault_lockbox_api::{
16 ArtifactKind, CacheLimit, CacheStats, ContactKeyPair, ContactPublicKey, ContentChunk,
17 ContentStreamOptions, ContentStreamOrder, Error, ExtractPolicy, FormDefinition,
18 FormFieldDefinition, FormFieldKind, FormFieldValue, FormRecord, FormTypeId, FormValue,
19 ImportStats, ListOptions, Lockbox, LockboxEntry, LockboxEntryKind, LockboxFileInspection,
20 LockboxFileMut, LockboxFileReader, LockboxId, LockboxInspector, LockboxKeySlot,
21 LockboxKeySlotAlgorithm, LockboxKeySlotProtection, LockboxOpen, LockboxOptions,
22 LockboxOwnerInspection, LockboxPath, LockboxProtection, MirrorMissingFilePolicy,
23 MirrorProject, OpenFileOptions, PageInspection, PageObjectInspection, ReadOnly,
24 RecoveryReport, RecoveryReportOptions, RecoveryScanner, Result, SecretString, SecretVec,
25 VariableName, VariableNamePattern, VariableSensitivity, VariableValueRef, WorkerPolicy,
26 WorkloadProfile, Writable, WritableLockboxState,
27 };
28
29 pub type ProfileSigningKeyPair = revault_lockbox_api::OwnerSigningKeyPair;
32
33 pub type ProfileSigningPublicKey = revault_lockbox_api::OwnerSigningPublicKey;
35
36 pub type WrappedContactKey = revault_lockbox_api::ContactWrappedKey;
38}
39
40pub mod vault {
42 use revault_lockbox_api::{ContactKeyPair, ContactPublicKey};
43
44 pub use revault_vault_api::{
45 backup_default_vault, decode_fingerprint_crockford_96, decode_fingerprint_hex,
46 default_vault_dir, default_vault_path, disable_platform_secret_store,
47 enable_platform_secret_store, encode_hex, export_private_key, export_public_key, forget,
48 forget_all, forget_platform_vault_password, forget_vault_unlock_key,
49 format_fingerprint_crockford_96, format_fingerprint_crockford_96_reading,
50 format_fingerprint_hex_pairs, get, get_platform_vault_password, get_vault_unlock_key,
51 import_private_key, import_private_key_file, import_public_key, is_running, list,
52 platform_secret_store_disabled, platform_secret_store_status, public_key_fingerprint, put,
53 put_platform_vault_password, put_vault_unlock_key, restore_default_vault, serve_agent,
54 set_auto_open_scope, start, stop, verify_agent_transport_security, AccessSlotLabel,
55 AgentSleepSupport, AutoOpenScope, CachedLockbox, ContentKeyStore, KeyFormat, KnownLockbox,
56 NoopStore, PlatformSecretStoreStatus, ProfileGeneration, ProfileGenerationStatus,
57 ProfileHistory, SecretActivityGuard, SecretActivityKind, SecretString, SecretVec,
58 StoredContact, VaultBackupManifest, CURRENT_VAULT_STRUCTURE_VERSION,
59 FINGERPRINT_CODE_96_LEN,
60 };
61
62 #[derive(Debug)]
68 pub struct Vault(revault_vault_api::VaultDirectory);
69
70 impl Vault {
71 pub fn open_default(password: &SecretString) -> revault_lockbox_api::Result<Self> {
73 let path = revault_vault_api::default_vault_path()?;
74 revault_vault_api::VaultDirectory::open_file(path, password).map(Self)
75 }
76 pub fn open_or_create_default(
78 password: &SecretString,
79 ) -> revault_lockbox_api::Result<Self> {
80 revault_vault_api::VaultDirectory::open_or_create_default(password).map(Self)
81 }
82 pub fn create_file(
84 path: impl AsRef<std::path::Path>,
85 password: &SecretString,
86 ) -> revault_lockbox_api::Result<Self> {
87 revault_vault_api::VaultDirectory::create_file(path, password).map(Self)
88 }
89 pub fn open_file(
91 path: impl AsRef<std::path::Path>,
92 password: &SecretString,
93 ) -> revault_lockbox_api::Result<Self> {
94 revault_vault_api::VaultDirectory::open_file(path, password).map(Self)
95 }
96 pub fn open_or_create(
98 root: impl AsRef<std::path::Path>,
99 password: &SecretString,
100 ) -> revault_lockbox_api::Result<Self> {
101 revault_vault_api::VaultDirectory::open_or_create(root, password).map(Self)
102 }
103 pub fn replace(
105 root: impl AsRef<std::path::Path>,
106 password: &SecretString,
107 ) -> revault_lockbox_api::Result<Self> {
108 revault_vault_api::VaultDirectory::replace(root, password).map(Self)
109 }
110 pub fn probe_structure_version(
112 root: impl AsRef<std::path::Path>,
113 password: &SecretString,
114 ) -> revault_lockbox_api::Result<u32> {
115 revault_vault_api::VaultDirectory::probe_structure_version(root, password)
116 }
117 pub fn root(&self) -> &std::path::Path {
119 self.0.root()
120 }
121 pub fn path(&self) -> &std::path::Path {
123 self.0.path()
124 }
125 pub fn structure_version(&self) -> revault_lockbox_api::Result<u32> {
127 self.0.structure_version()
128 }
129 pub fn store_private_key(
131 &self,
132 name: &str,
133 key: &ContactKeyPair,
134 ) -> revault_lockbox_api::Result<()> {
135 self.0.store_private_key(name, key)
136 }
137 pub fn load_private_key(&self, name: &str) -> revault_lockbox_api::Result<ContactKeyPair> {
139 self.0.load_private_key(name)
140 }
141 pub fn private_key_exists(&self, name: &str) -> revault_lockbox_api::Result<bool> {
143 self.0.private_key_exists(name)
144 }
145 pub fn list_private_keys(&self) -> revault_lockbox_api::Result<Vec<String>> {
147 self.0.list_private_keys()
148 }
149 pub fn delete_private_key(&self, name: &str) -> revault_lockbox_api::Result<()> {
151 self.0.delete_private_key(name)
152 }
153 pub fn store_profile_email(
155 &self,
156 name: &str,
157 email: &str,
158 ) -> revault_lockbox_api::Result<()> {
159 self.0.store_profile_email(name, email)
160 }
161 pub fn profile_email(&self, name: &str) -> revault_lockbox_api::Result<Option<String>> {
163 self.0.profile_email(name)
164 }
165 pub fn list_profile_generations(
167 &self,
168 name: &str,
169 ) -> revault_lockbox_api::Result<ProfileHistory> {
170 self.0.list_profile_generations(name)
171 }
172 pub fn rotate_private_key(
174 &self,
175 name: &str,
176 ) -> revault_lockbox_api::Result<ProfileHistory> {
177 self.0.rotate_private_key(name)
178 }
179 pub fn load_profile_signing_key(
181 &self,
182 name: &str,
183 ) -> revault_lockbox_api::Result<super::ProfileSigningKeyPair> {
184 self.0.load_owner_signing_key(name)
185 }
186 pub fn load_profile_signing_key_generation(
188 &self,
189 name: &str,
190 index: u16,
191 ) -> revault_lockbox_api::Result<super::ProfileSigningKeyPair> {
192 self.0.load_owner_signing_key_generation(name, index)
193 }
194 pub fn store_contact(
196 &self,
197 name: &str,
198 key: &ContactPublicKey,
199 ) -> revault_lockbox_api::Result<()> {
200 self.0.store_contact(name, key)
201 }
202 pub fn load_contact(&self, name: &str) -> revault_lockbox_api::Result<ContactPublicKey> {
204 self.0.load_contact(name)
205 }
206 pub fn contact_exists(&self, name: &str) -> revault_lockbox_api::Result<bool> {
208 self.0.contact_exists(name)
209 }
210 pub fn delete_contact(&self, name: &str) -> revault_lockbox_api::Result<()> {
212 self.0.delete_contact(name)
213 }
214 pub fn list_contacts(&self) -> revault_lockbox_api::Result<Vec<StoredContact>> {
216 self.0.list_contacts()
217 }
218 pub fn store_contact_signing_key(
220 &self,
221 name: &str,
222 key: &super::ProfileSigningPublicKey,
223 ) -> revault_lockbox_api::Result<()> {
224 self.0.store_contact_signing_key(name, key)
225 }
226 pub fn load_contact_signing_key(
228 &self,
229 name: &str,
230 ) -> revault_lockbox_api::Result<super::ProfileSigningPublicKey> {
231 self.0.load_contact_signing_key(name)
232 }
233 }
234
235 #[derive(Debug)]
237 pub struct ReadOnlyVault(revault_vault_api::ReadOnlyVaultDirectory);
238
239 impl ReadOnlyVault {
240 pub fn open_default(password: &SecretString) -> revault_lockbox_api::Result<Self> {
242 revault_vault_api::ReadOnlyVaultDirectory::open_default(password).map(Self)
243 }
244 pub fn open(
246 root: impl AsRef<std::path::Path>,
247 password: &SecretString,
248 ) -> revault_lockbox_api::Result<Self> {
249 revault_vault_api::ReadOnlyVaultDirectory::open(root, password).map(Self)
250 }
251 pub fn list_private_key_names(&self) -> revault_lockbox_api::Result<Vec<String>> {
253 self.0.list_private_key_names()
254 }
255 pub fn list_contact_names(&self) -> revault_lockbox_api::Result<Vec<String>> {
257 self.0.list_contact_names()
258 }
259 pub fn list_form_aliases(&self) -> revault_lockbox_api::Result<Vec<String>> {
261 self.0.list_form_aliases()
262 }
263 pub fn list_known_lockboxes(&self) -> revault_lockbox_api::Result<Vec<KnownLockbox>> {
265 self.0.list_known_lockboxes()
266 }
267 }
268
269 #[derive(Debug, Clone, Copy, Default)]
272 pub struct AgentSession;
273
274 impl AgentSession {
275 pub const fn instance() -> Self {
277 Self
278 }
279 pub fn start(&self) -> std::io::Result<()> {
281 revault_vault_api::start()
282 }
283 pub fn stop(&self) -> std::io::Result<()> {
285 revault_vault_api::stop()
286 }
287 pub fn close_all(&self) -> std::io::Result<()> {
289 revault_vault_api::forget_all()
290 }
291 pub fn profile_signing_key(
296 &self,
297 vault_id: &str,
298 profile: &str,
299 ) -> std::io::Result<Option<super::ProfileSigningKeyPair>> {
300 revault_vault_api::get_owner_signing_key(vault_id, profile)
301 }
302 pub fn cache_profile_signing_key(
304 &self,
305 vault_id: &str,
306 profile: &str,
307 key: super::ProfileSigningKeyPair,
308 ttl_seconds: Option<u64>,
309 ) -> std::io::Result<()> {
310 revault_vault_api::put_owner_signing_key(vault_id, profile, key, ttl_seconds)
311 }
312 pub fn forget_profile_signing_key(
314 &self,
315 vault_id: &str,
316 profile: &str,
317 ) -> std::io::Result<()> {
318 revault_vault_api::forget_owner_signing_key(vault_id, profile)
319 }
320 pub fn is_running(&self) -> bool {
322 revault_vault_api::is_running()
323 }
324 pub fn serve(&self) -> std::io::Result<()> {
326 revault_vault_api::serve_agent()
327 }
328 }
329}
330
331pub use lockbox::{ProfileSigningKeyPair, ProfileSigningPublicKey, WrappedContactKey};
332pub use revault_lockbox_api::{ContactKeyPair, ContactPublicKey, Lockbox};
333pub use vault::{AgentSession, ReadOnlyVault, Vault};
334
335#[derive(Debug, Clone, Copy, Default)]
341pub struct Revault;
342
343impl Revault {
344 pub const fn load() -> Self {
351 Self
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 use super::{AgentSession, ProfileSigningKeyPair, ReadOnlyVault, Revault, Vault};
358
359 #[test]
360 fn reviewed_runtime_and_profile_identity_are_process_local() {
361 let _runtime = Revault::load();
362 let session = AgentSession::instance();
363 let _running = session.is_running();
364 let signing_key = ProfileSigningKeyPair::generate().expect("generate profile key");
365 let public_key = signing_key.public_key();
366 assert!(!public_key.to_bytes().is_empty());
367
368 let root = std::env::temp_dir().join(format!(
369 "revault-api-facade-{}-{}",
370 std::process::id(),
371 public_key.to_bytes()[0]
372 ));
373 let passphrase = super::vault::SecretString::try_from_slice(b"facade test passphrase")
374 .expect("construct vault passphrase");
375 let vault = Vault::replace(&root, &passphrase).expect("replace test Vault");
376 assert!(vault.structure_version().expect("read structure version") > 0);
377 drop(vault);
378 let readonly = ReadOnlyVault::open(&root, &passphrase).expect("open read-only Vault");
379 assert!(readonly
380 .list_private_key_names()
381 .expect("list profile names")
382 .is_empty());
383 let _ = std::fs::remove_dir_all(root);
384 }
385}