Secure, typed, async Rust SDK for OpenBao.
Memory-safe Rust API. Reviewed dependency surface. Built for audited secret workflows.
Secure, typed, async Rust SDK for OpenBao. The crate is designed for audited secret workflows: HTTPS and TLS 1.3 by default, disabled redirects, strict path and response bounds, secret-aware values, and fail-closed server-version compatibility.
Credential-bearing OIDC/JWKS, Kubernetes, RabbitMQ, LDAP, Kerberos LDAP, and reviewed database configurations also require encrypted service-side transport; the SDK validates both the client-to-OpenBao and configured OpenBao-to-backend boundaries.
API documentation | Source | Security | Releases
2.2.5 adds exact OpenBao 2.6.5 and 2.7.2 profiles and refreshes the
reviewed official external-plugin set. It retains Rust 1.99.1 as the primary
toolchain and Rust 1.90.0 as the MSRV. The known upstream control-group
single-use enforcement limitation remains present in OpenBao 2.7.2; use the
operational restrictions in the security documentation for affected workflows.
| Plugin | Reviewed version | Linux amd64 v1 binary SHA-256 | Tested OpenBao |
|---|---|---|---|
| LDAP authentication | v0.2.0 |
b323b200b2dec50199f36de7dc95a661ce6662da3d53905973c0d7700b4185bb |
2.7.0, 2.7.1, 2.7.2 |
| LDAP secrets | v0.1.1 |
4b24d4deec624d76bd8f950dfaf6f59822de14cfb9bd344e2e7c4c492cc77789 |
2.7.0, 2.7.1, 2.7.2 |
| Kerberos authentication | v0.1.0 |
57ac030fea755adf791600eb2b30aa410d2e848ab7ec7bb54cc515cdce4b89ae |
2.7.0, 2.7.1, 2.7.2 |
| RADIUS authentication | v0.2.0 |
ae2ac43287ed297a9536456b0cbb79c8749a82ffe74a54e3fe886d3285443f07 |
2.7.0, 2.7.1, 2.7.2 |
Plugin pins are normally refreshed and retested when an OpenBao compatibility release is prepared. A routine plugin-only patch does not by itself trigger an SDK release; a relevant security fix or compatibility break may trigger an earlier review. Only the exact versions and server pairs in this table are supported. External plugins require a verified exact server and explicit artifact/mount selection, not merely a server profile.
| Rust version | Support policy |
|---|---|
1.99.1 |
Primary toolchain for development and CI. |
1.90.0 |
Minimum supported Rust version; separately checked in CI. |
1.91.0 through 1.98.x |
Within the supported range; not individually tested on every commit. |
See the 2.2.5 release notes for maintenance changes and trust boundaries, the 2.2.1 release notes for the OIDC secret-field migration and explicit limitations, and the 2.2.0 release notes for migration changes. The onboarding history records the implementation and review checkpoints.
Clients without a compatibility policy retain the
unverified 2.6.3 API contract. Select an explicit profile (preferably exact or
automatic strict verification) to use 2.7 controls. LDAP auth/secrets, Kerberos
and RADIUS on 2.7 additionally require ExternalPluginSelection; see the
plugin selection guide.
Selection asserts the deployment's installed artifact; it is not remote
attestation. RADIUS still requires radius-auth-acknowledged and audited
transport protection.
[dependencies]
openbao = "2.2.5"
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }Default features select the Rustls TLS backend and the primary authentication, secret-engine, and system APIs. Capabilities with additional security or dependency costs are opt-in; see Feature Selection.
The environment constructor reads the supported OPENBAO_*, BAO_*, and
VAULT_* aliases. The authenticated variant validates the token before the
first request.
use openbao::{Client, Result};
#[tokio::main]
async fn main() -> Result<()> {
let client = Client::from_env_with_token()?;
let health = client.sys().health().await?;
println!("sealed: {}", health.sealed);
Ok(())
}Typed secret responses let applications select which fields require secret storage:
use openbao::{Client, Result, SecretString};
use serde::Deserialize;
#[derive(Deserialize)]
struct DatabaseCredentials {
username: String,
password: SecretString,
}
#[tokio::main]
async fn main() -> Result<()> {
let client = Client::from_env_with_token()?;
let secret = client
.kv2("secret")?
.read::<DatabaseCredentials>("production/database")
.await?;
let _username = secret.data.username;
let _password = secret.data.password;
Ok(())
}Do not print or serialize secret values into diagnostics. SecretString and
the crate's secret response types redact Debug, but exposing a secret remains
an explicit application responsibility. In 2.1.7, openbao::SecretString
is provided by sanitization-secrecy rather than the upstream secrecy crate.
Code using the OpenBao re-export keeps the same imports; code passing a direct
upstream secrecy::SecretString must migrate to openbao::SecretString.
Transit request bodies and complete response accumulators use sanitizing
SDK-owned storage, but this is not a complete process-memory-erasure guarantee.
Shared HTTP chunks and serde_json, reqwest, Hyper, TLS, allocator, kernel, and
device buffers remain outside SDK cleanup control; see the security model for
the stage-by-stage ownership boundary.
The /v1 URL prefix is not an API-version guarantee. Use strict automatic
selection for normal deployments or an exact policy when the server release is
pinned:
use openbao::{
Client, OpenBaoCompatibilityPolicy, OpenBaoConfig, OpenBaoVersion, Result,
};
fn exact_openbao_2_2() -> Result<Client> {
let policy = OpenBaoCompatibilityPolicy::exact(OpenBaoVersion::new(2, 2, 0))?;
let config = OpenBaoConfig::new("https://bao.example.com:8200")?
.compatibility_policy(policy);
Client::from_config(config)
}The first compatible operation performs a token-free /sys/health probe and
caches the selected profile in that client. A mismatch fails before a typed
operation is sent. Rolling ranges verify only the backend that answered the
probe, so mixed clusters still require backend affinity or use of the common
capability intersection.
See the source documentation for the complete policy:
The typed API includes:
- AppRole, token, certificate, Kubernetes, JWT/OIDC, LDAP, RADIUS, Kerberos, and userpass authentication;
- KV v1/v2, Cubbyhole, Kubernetes, RabbitMQ, LDAP, database, Transit, PKI, TOTP, and SSH secret engines;
- Identity entities, groups, aliases, OIDC providers, and MFA administration;
- health, readiness, mounts, audit devices, leases, policies, capabilities, namespaces, Raft, quotas, plugins, wrapping, metrics, and system tools;
- OpenBao 2.6 workflows, JWT CEL roles, identity-template controls, userpass bcrypt hashes, and sealable namespaces;
- OpenBao 2.7 external-key administration, Transit/PKI ML-DSA and KMS options, control groups, guarded workflow CAS and opt-in consistency transport; and
- idempotent bootstrap convergence for common application-owned resources.
Destructive operator ceremonies, raw transports, unstable internal endpoints, credential-bearing URL query flows, and other high-risk operations require explicit feature acknowledgements. This keeps them unavailable to ordinary builds while retaining typed support for reviewed operator tooling.
Detailed inventories:
Important non-default features include:
| Feature | Purpose |
|---|---|
http2 |
Enable HTTP/2 negotiation through TLS ALPN. |
consistency |
Scoped consistency transport and bounded metadata for verified 2.7 profiles. Source-bound live multi-node, controlled-lag, cancellation and cross-cluster evidence is retained. |
time |
Parse timestamps into time crate types. |
tokio-helpers |
Add Tokio-backed bounded readiness waits. |
tracing |
Emit redacted request spans without an OpenTelemetry SDK dependency. |
monitor-stream |
Expose bounded, secret-aware system log streaming. |
raft-stream |
Stream large Integrated Storage restore bodies. |
transit-bytes |
Add secret byte encode/decode helpers. |
transit-import |
Add software Transit BYOK wrapping; also requires transit-import-acknowledged. |
memory-lock |
Keep the authenticated client's retained token in locked mapped memory; also requires memory-lock-acknowledged. |
operator-ops |
Expose production operator ceremonies; also requires operator-ops-acknowledged. |
raw-api |
Expose generic transports; also requires raw-api-acknowledged. |
unstable-internal-ops |
Expose unstable OpenBao internal endpoints with both operator and unstable acknowledgements. |
Several protocol-specific features have matching -acknowledged gates. Cargo
will reject incomplete high-risk feature combinations at compile time. Review
the complete feature list and
the detailed security model before enabling one.
Key defaults and controls:
unsafe_code = "forbid"for this crate's own Rust sources; TLS and cryptographic dependencies can contain unsafe Rust, FFI, assembly, or native code and remain part of the trusted computing base;- Rustls and TLS 1.3 by default;
- root-only private-CA trust and static CRL support;
- redirects disabled;
- bounded request and response bodies;
- validated paths, headers, CIDRs, durations, and collection sizes;
- redacted API errors, tracing fields, tokens, accessors, and credential types;
- immutable OpenBao compatibility profiles without fallback route probing;
- optional fail-closed locked storage for the retained client token; and
- dependency, RustSec, package, Kani, compatibility, and pentest release gates.
HTTP, TLS, allocator, kernel, and device layers can retain secret copies beyond
the buffers controlled by this crate. SDK-owned JSON, form, and byte request
body allocations are wiped after their final HTTP-body owner drops, and
uniquely owned receive chunks are wiped after copying into SecretVec.
Other request and response secrets are not automatically locked by the
memory-lock feature. High-assurance users must review process isolation,
core dumps, swap, memory-lock quotas, TLS termination, and feature selection.
Read SECURITY.md for reporting and baseline policy. The
detailed security model
records feature-specific controls, residual risks, and hardened deployment
guidance.
The repository contains compiled examples rather than duplicating dozens of unchecked Markdown programs:
- environment client;
- KV v2;
- AppRole login;
- exact OpenBao 2.2 profile;
- admin bootstrap;
- system administration.
Additional repository documentation:
Repository-only compatibility fixtures, integration harnesses, fuzz targets, formal proofs, release scripts, and historical evidence remain available in the signed source tag without being copied into the crates.io archive.
From a checkout, run the standard gate with:
scripts/checks.shEvery release additionally requires version-locked OpenBao integration,
package verification, a reviewed pentest report, and the matching release
gate. Release history is recorded in CHANGELOG.md and
GitHub releases.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE);
- MIT License (LICENSE-MIT).
