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<AgeVaultProvider, AgeVaultError>
pub fn new( key_path: &Path, vault_path: &Path, ) -> Result<AgeVaultProvider, 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<AgeVaultProvider, AgeVaultError>
pub fn load( key_path: &Path, vault_path: &Path, ) -> Result<AgeVaultProvider, 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.Trait Implementations§
Source§impl Debug for AgeVaultProvider
impl Debug for AgeVaultProvider
Auto Trait Implementations§
impl Freeze for AgeVaultProvider
impl RefUnwindSafe for AgeVaultProvider
impl Send for AgeVaultProvider
impl Sync for AgeVaultProvider
impl Unpin for AgeVaultProvider
impl UnsafeUnpin for AgeVaultProvider
impl UnwindSafe for AgeVaultProvider
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request