pub struct AgeVaultProvider { /* private fields */ }Expand description
Age-encrypted vault backend.
Secrets are stored as a JSON object ({"KEY": "value", ...}) encrypted with an x25519
keypair using the age format. The in-memory secret values
are held in zeroize::Zeroizing buffers.
§File layout
<dir>/vault-key.txt # age identity (private key), Unix mode 0600
<dir>/secrets.age # age-encrypted JSON object§Initialising a new vault
Use AgeVaultProvider::init_vault to generate a fresh keypair and create an empty vault:
use std::path::Path;
use zeph_vault::AgeVaultProvider;
AgeVaultProvider::init_vault(Path::new("/etc/zeph"))?;
// Produces:
// /etc/zeph/vault-key.txt (mode 0600)
// /etc/zeph/secrets.age (empty encrypted vault)§Atomic writes
save writes to a .age.tmp sibling file first, then renames it
atomically, so a crash during write never leaves the vault in a corrupted state.
Implementations§
Source§impl AgeVaultProvider
impl AgeVaultProvider
Sourcepub fn new(key_path: &Path, vault_path: &Path) -> Result<Self, AgeVaultError>
pub fn new(key_path: &Path, vault_path: &Path) -> Result<Self, AgeVaultError>
Decrypt an age-encrypted JSON secrets file.
This is an alias for load provided for ergonomic construction.
§Arguments
key_path— path to the age identity (private key) file. Lines starting with#and blank lines are ignored; the first non-comment line is parsed as the identity.vault_path— path to the age-encrypted JSON file.
§Errors
Returns AgeVaultError on key/vault read failure, parse error, or decryption failure.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let vault = AgeVaultProvider::new(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
println!("{} secrets loaded", vault.list_keys().len());Sourcepub fn load(key_path: &Path, vault_path: &Path) -> Result<Self, AgeVaultError>
pub fn load(key_path: &Path, vault_path: &Path) -> Result<Self, AgeVaultError>
Load vault from disk, storing paths for subsequent write operations.
Reads and decrypts the vault, then retains both paths so that
save can re-encrypt and persist changes without requiring callers to
pass paths again.
§Errors
Returns AgeVaultError on key/vault read failure, parse error, or decryption failure.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;Sourcepub fn save(&self) -> Result<(), AgeVaultError>
pub fn save(&self) -> Result<(), AgeVaultError>
Serialize and re-encrypt secrets to vault file using atomic write (temp + rename).
Re-reads and re-parses the key file on each call. For CLI one-shot use this is acceptable; if used in a long-lived context consider caching the parsed identity.
§Errors
Returns AgeVaultError on encryption or write failure.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let mut vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
vault.set_secret_mut("MY_TOKEN".into(), "tok_abc123".into());
vault.save()?;Sourcepub fn set_secret_mut(&mut self, key: String, value: String)
pub fn set_secret_mut(&mut self, key: String, value: String)
Insert or update a secret in the in-memory map.
Call save afterwards to persist the change to disk.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let mut vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
vault.set_secret_mut("API_KEY".into(), "sk-...".into());
vault.save()?;Sourcepub fn remove_secret_mut(&mut self, key: &str) -> bool
pub fn remove_secret_mut(&mut self, key: &str) -> bool
Remove a secret from the in-memory map.
Returns true if the key existed and was removed, false if it was not present.
Call save afterwards to persist the removal to disk.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let mut vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
let removed = vault.remove_secret_mut("OLD_KEY");
if removed {
vault.save()?;
}Sourcepub fn list_keys(&self) -> Vec<&str>
pub fn list_keys(&self) -> Vec<&str>
Return sorted list of secret keys (no values exposed).
Keys are returned in ascending lexicographic order. Secret values are never included.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
for key in vault.list_keys() {
println!("{key}");
}Sourcepub fn get(&self, key: &str) -> Option<&str>
pub fn get(&self, key: &str) -> Option<&str>
Look up a secret value by key, returning None if not present.
Returns a borrowed &str tied to the lifetime of the vault. For async use across await
points, use VaultProvider::get_secret instead, which returns an owned String.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
let vault = AgeVaultProvider::load(
Path::new("/etc/zeph/vault-key.txt"),
Path::new("/etc/zeph/secrets.age"),
)?;
match vault.get("ZEPH_OPENAI_API_KEY") {
Some(key) => println!("key length: {}", key.len()),
None => println!("key not configured"),
}Sourcepub fn init_vault(dir: &Path) -> Result<(), AgeVaultError>
pub fn init_vault(dir: &Path) -> Result<(), AgeVaultError>
Generate a new x25519 keypair, write the key file (mode 0600), and create an empty encrypted vault.
Creates dir and all missing parent directories before writing files. Existing files
are not checked — calling this on an already-initialised directory will overwrite both
the key and the vault, making the old key irrecoverable.
§Output files
| File | Contents | Unix mode |
|---|---|---|
<dir>/vault-key.txt | age identity (private + public key comment) | 0600 |
<dir>/secrets.age | age-encrypted empty JSON object {} | default |
§Errors
Returns AgeVaultError on key/vault write failure or encryption failure.
§Examples
use std::path::Path;
use zeph_vault::AgeVaultProvider;
AgeVaultProvider::init_vault(Path::new("/etc/zeph"))?;
// /etc/zeph/vault-key.txt and /etc/zeph/secrets.age are now ready.