Skip to content

Rust

Depend on the tag the v0.1.3 release was cut from:

[dependencies]
sourceorrery = { git = "https://github.com/Netizine/sourceorrery", tag = "v0.1.3" }
[dependencies]
sourceorrery = "0.1"

Every release is on crates.io, as are the crates it depends on.

The sourceorrery crate is the read-only client every other SDK is built on. It depends on sourceorrery-storage directly (no C ABI in between) and, like the CLI, needs a C compiler for the bundled SQLite. The os-keyring feature (default) enables the OS credential store; disable it for headless servers that only use passphrases.

use sourceorrery::SecretReader;
let reader = SecretReader::open("development")?;
let secret = reader.get("database-password")?;
connect(secret.value.expose());
// `secret.value` is a SecretBytes: zeroised on drop, redacted in Debug, no Serialize

SecretReader::open behaves like the CLI: SOURCEORRERY_HOME locates the vault; the OS credential store, then SOURCEORRERY_PASSPHRASE, then SOURCEORRERY_PASSPHRASE_FILE unlock it; there is never a prompt. SecretReader::open_with(vault, &OpenOptions) takes a home, a passphrase, a passphrase_file and environment(false) to ignore the two passphrase variables.

Call Returns
reader.get(name) Secret for the newest accessible version
reader.get_version(name, version) Secret for exactly that version
reader.properties(name, Some(version)) SecretProperties (policy not applied)
reader.resolve("sourceorrery://development/database-password") Secret
reader.descriptor() VaultDescriptor (no values)

Secret, SecretProperties, SecretBytes and SecretReference are the core’s own types, re-exported. A SecretReader is Send + Sync.

Every method returns sourceorrery::Result<T>; the error carries the stable code, an ErrorKind, the message and a hint:

use sourceorrery::{ErrorKind, SecretReader};
match SecretReader::open("development").and_then(|r| r.get("database-password")) {
Ok(secret) => { /* ... */ }
Err(err) if err.kind() == ErrorKind::Locked => eprintln!("{}", err.hint()),
Err(err) if err.kind().is_policy() => eprintln!("{} (retry later: {})", err, err.is_transient()),
Err(err) => eprintln!("[{}] {err}", err.code()), // Display = message + hint
}

ErrorKind has a variant per code (NotFound, VersionNotFound, Deleted, Disabled, NotYetValid, Expired, InvalidName, InvalidArgument, PermissionDenied, Locked, VaultNotFound, MigrationRequired, Manifest, Crypto, Storage, Io, Unsupported) plus Other for codes added later. See the SDK overview for what each hint says.

use sourceorrery::{OpenOptions, Project};
let project = Project::load(Some(std::path::Path::new("sourceorrery.toml")), &OpenOptions::new())?;
for secret in project.secrets() {
// secret.env, secret.reference, secret.properties, secret.value
}
let pairs = project.into_env(); // Vec<(String, SecretBytes)>

Project::load(None, ..) discovers the nearest sourceorrery.toml above the current directory. It mirrors sourceorrery run: a required secret that cannot be read fails the load with that secret’s error; optional ones are left out.

Terminal window
cargo run -p sourceorrery --example get_secret -- development database-password
cargo test -p sourceorrery

Source: crates/sourceorrery.