SDKs
SourceOrrery ships a read-only client for ten languages. Each one does the same five things and nothing more:
| Open a vault | by name, unlocked the way the CLI unlocks it: the OS credential store first, then SOURCEORRERY_PASSPHRASE, then SOURCEORRERY_PASSPHRASE_FILE; never an interactive prompt. SOURCEORRERY_HOME says where vaults live. |
| Get a secret | the newest accessible version (enabled, inside its time window) or an explicit version. |
| Read properties | metadata of a version, without policy, so disabled and expired versions can be inspected. |
| Resolve a reference | sourceorrery://vault/name[/version], the form the manifest and the CLI use. |
| Load a project | every secret a sourceorrery.toml declares, resolved like sourceorrery run: required secrets must resolve, optional ones that cannot are left out. |
There is no set, update, delete, recover or purge, no protector
and no audit management in any SDK. Writing is the CLI’s job; a library
that cannot write cannot be tricked into writing
(ADR 0005).
| Language | Package | Technology | Guide |
|---|---|---|---|
| Python | sourceorrery on PyPI |
PyO3 + maturin, abi3 wheels (3.11+) | Python |
| JavaScript / TypeScript | @sourceorreryai/sdk on npm |
napi-rs native addon, types included | JavaScript |
| Rust | sourceorrery on crates.io |
the client crate itself | Rust |
| Java | ai.sourceorrery:sourceorrery on Maven Central |
Foreign Function and Memory API (Java 22+) | Java |
| .NET | SourceOrrery on NuGet |
LibraryImport P/Invoke (.NET 8+) |
.NET |
| Go | github.com/netizine/sourceorrery/bindings/go |
cgo | Go |
| C | sourceorrery.h in the release archive |
the C ABI | C |
| C++ | sourceorrery.hpp in the release archive |
header-only RAII wrapper | C++ |
| PHP | sourceorrery/sourceorrery on Packagist |
the FFI extension | PHP |
Why each technology: ADR 0006.
Installing
Section titled “Installing”0.1.3 is on PyPI, crates.io, Maven Central, NuGet, Packagist and npm
(under the @sourceorreryai scope), and the Go module on pkg.go.dev.
Every package is also on the
v0.1.3 GitHub release
(wheels, the jar, the NuGet package, the npm tarballs, and the C ABI
archive the Go, C, C++ and PHP bindings load), and each language page opens
with how to install from it.
Setting up
Section titled “Setting up”Every SDK reads a vault that already exists, so the first steps are the CLI’s:
sourceorrery vault create development # OS credential storesourceorrery secret set database-password --vault developmentOn a server, in a container or in CI there is no credential store: give the vault a passphrase protector and hand the passphrase to the process.
sourceorrery vault protector add --kind passphrase --vault developmentexport SOURCEORRERY_PASSPHRASE=... # or SOURCEORRERY_PASSPHRASE_FILE=/run/secrets/vaultEach SDK also accepts a passphrase, a passphrase file and a home directory in code, for tests and unusual layouts. Prefer the environment or a file in production: process arguments and source code are visible to more people.
Errors
Section titled “Errors”Every failure carries the core’s stable error code, a message and a hint: one actionable sentence produced by the Rust core, so every language says the same thing.
| Code | Typed error | Hint says |
|---|---|---|
vault_not_found |
VaultNotFound… |
how to create the vault with the CLI, and which home directory was searched |
locked |
VaultLocked… |
which passphrase sources were tried (option, SOURCEORRERY_PASSPHRASE, SOURCEORRERY_PASSPHRASE_FILE) and how to add a protector |
migration_required |
MigrationRequired… |
run sourceorrery vault migrate <name>; SDKs never migrate |
not_found |
SecretNotFound… |
how to store the secret (sourceorrery secret set) |
version_not_found |
VersionNotFound… (a SecretNotFound…) |
list versions, or omit the version |
disabled, not_yet_valid, expired |
SecretDisabled…, SecretNotYetValid…, SecretExpired… (all Policy…) |
the policy decision and the secret update that changes it; not_yet_valid is marked transient |
deleted |
SecretDeleted… |
sourceorrery secret recover |
crypto |
Integrity… |
the file failed an integrity check: compare with a backup, run audit --verify |
unsupported |
Unsupported… |
no OS credential store here: add a passphrase protector |
invalid_argument, invalid_name |
InvalidArgument…, InvalidName… |
the reference and name rules |
manifest |
Manifest… |
fix sourceorrery.toml, check with sourceorrery check |
| anything newer | the base type, code preserved |
Names follow each language’s conventions (SecretNotFoundError in
Python, SecretNotFoundException in Java, ErrNotFound sentinel in Go,
and so on). No error, message or hint ever contains a secret value.
Values
Section titled “Values”A value is held in native memory until the application closes it, and the
library zeroises it then. The wrapper type prints as [REDACTED], refuses
to be serialised where the language allows it, and hands the bytes out only
through an explicit call (expose(), Text(), ExposeText()). Once an
application copies the bytes out, keeping them safe is the application’s
job: a Python str, a Java String or a JavaScript string cannot be
wiped, so keep such copies short-lived.
How the SDKs are tested
Section titled “How the SDKs are tested”Every SDK has a test suite and an example that CI runs on Ubuntu, Windows
and macOS against a vault the job creates with the CLI
(scripts/ci/fixture-vault.sh: a passphrase protector,
SOURCEORRERY_PASSPHRASE in the environment, secrets covering every
policy state). A binding whose tests do not pass does not ship.
On top of the per-language suites, one conformance harness holds every
SDK to the same contract: tests/conformance/sdk/scenarios.json lists the
scenarios (unlock sources, latest and explicit versions, references,
policy refusals, missing secrets, project loading, with the codes,
messages and hints each must produce), each SDK ships a small runner
that executes one scenario, and tests/conformance/sdk/harness.py drives
a runner through all of them and judges the observations. CI runs it in
every SDK job; the protocol and how to add a scenario are in
tests/conformance/sdk/README.md.
To run them locally:
cargo build --release -p sourceorrery-cli -p sourceorrery-ffieval "$(bash scripts/ci/fixture-vault.sh)"# then, per language, what its page says under "Building from source", andpython tests/conformance/sdk/harness.py --runner python # or rust, node, java, dotnet, go, c, cpp, phpReleases: release.md.