Struct ZeroKMSBuilder
pub struct ZeroKMSBuilder<C, ClientKeyState = ()> { /* private fields */ }Expand description
A builder for creating ZeroKMS and ZeroKMSWithClientKey clients.
The ZeroKMS endpoint is resolved in this order:
- Explicit URL via
with_base_url CS_ZEROKMS_HOST(or legacyCS_VITUR_HOST) environment variable- Automatically from the token’s
servicesclaim
§Examples
§Basic usage with AutoStrategy
use cipherstash_client::zerokms::ZeroKMSBuilder;
use stack_auth::AutoStrategy;
let strategy = AutoStrategy::detect()?;
let zerokms = ZeroKMSBuilder::new(strategy)
.with_request_timeout(30)
.with_max_concurrent_reqs(20)
.build()?;§With client key for encryption/decryption
use cipherstash_client::zerokms::{ZeroKMSBuilder, ClientKey};
use stack_auth::AutoStrategy;
use uuid::Uuid;
let strategy = AutoStrategy::detect()?;
let client_id = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
let client_key = ClientKey::from_hex_v1(client_id, "a4627031...")?;
let zerokms = ZeroKMSBuilder::new(strategy)
.with_client_key(client_key)
.build()?;§With a foreign-defined strategy (FFI / custom callback)
ZeroKMSBuilder::new accepts any type whose references implement
stack_auth::AuthStrategy. stack_auth::AuthStrategyFn wraps an
async closure into that shape — the canonical seam for crates like
protect-ffi that source the token across an FFI boundary (a JS
getToken() call, a foreign IPC channel, etc).
use cipherstash_client::zerokms::ZeroKMSBuilder;
use stack_auth::{AuthStrategyFn, SecretToken, ServiceToken};
let strategy = AuthStrategyFn::new(|| async {
// Real consumers call into FFI / IPC / their own cache.
Ok(ServiceToken::new(SecretToken::new("dummy.jwt.value".to_string())))
});
let zerokms = ZeroKMSBuilder::new(strategy).build()?;§Tuning for bulk ingest vs interactive workloads
The defaults — request_timeout 10 s, max_keys_per_req 500,
max_concurrent_reqs 5 — are tuned for the interactive case (proxy
query-rewrite, single-document encrypt/decrypt) where fast failure on
network problems matters more than absolute throughput.
Bulk ingest (large backfills, batch ETL, our cipherstash/benches
suite) wants the opposite trade-off: longer per-request budgets to
absorb p99 latency spikes, and persistent connection pools so cold
TLS handshakes don’t dominate. Recommended starting point:
use cipherstash_client::zerokms::ZeroKMSBuilder;
let zerokms = ZeroKMSBuilder::auto()?
// Connect phase fast-fail: if you can't open TCP+TLS in 5 s the
// network is broken; no point waiting longer.
.with_connect_timeout(5)
// Generous request budget — server-side processing time scales
// with `keys.len()`, and bulk callers care more about completing
// the batch than about failing fast.
.with_request_timeout(60)
// Keep warm TLS connections alive across idle gaps between
// batches; default is 90 s which is short for some pipelines.
.with_pool_idle_timeout(600)
// Reduce per-request server work when responses are slow;
// smaller batches lower the chance any single request times out.
.with_max_keys_per_req(100)
// Increase parallelism to compensate for the smaller batches.
.with_max_concurrent_reqs(20)
.build()?;Importantly: build once, hold an Arc for the process lifetime.
Recreating the client (or the ScopedCipher)
on every batch discards the warm reqwest connection pool and forces
every encrypt to pay the cold-start cost (DNS + TCP + TLS handshake).
Auth tokens auto-refresh through stack_auth::AutoRefresh underneath
the same client — no manual rotation needed.
Implementations§
§impl ZeroKMSBuilder<AutoStrategy, ()>
impl ZeroKMSBuilder<AutoStrategy, ()>
pub fn auto() -> Result<Self, ZeroKMSBuilderError>
pub fn auto() -> Result<Self, ZeroKMSBuilderError>
Create a ZeroKMSBuilder that automatically detects credentials from the environment.
This is the recommended entry point for most use cases. It uses AutoStrategy
to detect available credentials (access key or OAuth token) and resolves the ZeroKMS
endpoint from the token’s services claim.
§Examples
use cipherstash_client::zerokms::ZeroKMSBuilder;
let zerokms = ZeroKMSBuilder::auto()?.build()?;§impl<C> ZeroKMSBuilder<C, ()>
impl<C> ZeroKMSBuilder<C, ()>
pub fn new(credentials: C) -> Self
pub fn new(credentials: C) -> Self
Create a new ZeroKMSBuilder.
§Arguments
credentials- Credentials provider for obtaining access tokens
pub fn with_request_timeout(self, timeout_secs: u64) -> Self
pub fn with_request_timeout(self, timeout_secs: u64) -> Self
Set the total request timeout in seconds — covers connect + TLS handshake + body send + body receive together.
If not set, defaults to 10 seconds. Bulk-ingest callers typically
want this larger (30–60 s) — see the “Tuning for bulk ingest”
section on ZeroKMSBuilder.
pub fn with_connect_timeout(self, timeout_secs: u64) -> Self
pub fn with_connect_timeout(self, timeout_secs: u64) -> Self
Set the connect timeout in seconds — bound on TCP connect + TLS handshake only, separate from the total request timeout.
If not set, reqwest falls back to the OS-level connect timeout (~75 s on most platforms). Setting this small (e.g. 5 s) gives fast-fail on broken networks without forcing the total request timeout to absorb both connect and response time.
pub fn with_pool_idle_timeout(self, timeout_secs: u64) -> Self
pub fn with_pool_idle_timeout(self, timeout_secs: u64) -> Self
Set the pool idle timeout in seconds — how long the underlying reqwest client keeps idle keep-alive connections in its pool before closing them.
If not set, reqwest’s default of 90 s applies. Long-lived processes (bulk ingest, daemons) benefit from raising this so warm TLS connections survive idle gaps between batches.
pub fn with_max_keys_per_req(self, max_keys: usize) -> Self
pub fn with_max_keys_per_req(self, max_keys: usize) -> Self
Set the maximum number of keys per request.
Defaults to 500 if not set.
pub fn with_max_concurrent_reqs(self, max_concurrent: usize) -> Self
pub fn with_max_concurrent_reqs(self, max_concurrent: usize) -> Self
Set the maximum number of concurrent requests.
Defaults to 5 if not set.
pub fn with_base_url(self, base_url: Url) -> Self
pub fn with_base_url(self, base_url: Url) -> Self
Override the base URL for the ZeroKMS service.
This bypasses resolving the URL from the token’s services claim and connects
directly to the specified URL. Useful for:
- Connecting to local development servers
- Testing against non-production environments
- Custom deployment configurations
pub fn with_key_provider<K: KeyProvider>(
self,
provider: K,
) -> ZeroKMSBuilder<C, WithKeyProvider<K>>
pub fn with_key_provider<K: KeyProvider>( self, provider: K, ) -> ZeroKMSBuilder<C, WithKeyProvider<K>>
Add a KeyProvider to load a client key asynchronously at build time.
This transforms the builder into one that will build a ZeroKMSWithClientKey
via an async build() call.
Use this instead of with_client_key when the key needs to be
loaded from an external source (environment variables, keychain, etc.).
§Example
use cipherstash_client::zerokms::{
ZeroKMSBuilder, EnvKeyProvider, FallbackKeyProvider,
};
use stack_profile::ProfileStore;
use stack_auth::AutoStrategy;
let strategy = AutoStrategy::detect()?;
// Try environment variables first, fall back to the on-disk profile
let zerokms = ZeroKMSBuilder::new(strategy)
.with_key_provider(FallbackKeyProvider::new(
EnvKeyProvider,
ProfileStore::default(),
))
.build()
.await?;pub fn with_client_key(
self,
client_key: ClientKey,
) -> ZeroKMSBuilder<C, ClientKey>
pub fn with_client_key( self, client_key: ClientKey, ) -> ZeroKMSBuilder<C, ClientKey>
Add a client key to enable encryption and decryption operations.
This transforms the builder into one that will build a ZeroKMSWithClientKey instead of a plain ZeroKMS.
pub fn build(self) -> Result<ZeroKMS<C>, ZeroKMSBuilderError>
pub fn build(self) -> Result<ZeroKMS<C>, ZeroKMSBuilderError>
Build a ZeroKMS client.
The ZeroKMS endpoint is resolved from (in order): an explicit
with_base_url override, the CS_ZEROKMS_HOST
or the token’s services claim.
§impl<C> ZeroKMSBuilder<C, ClientKey>
impl<C> ZeroKMSBuilder<C, ClientKey>
pub fn build(self) -> Result<ZeroKMSWithClientKey<C>, ZeroKMSBuilderError>
pub fn build(self) -> Result<ZeroKMSWithClientKey<C>, ZeroKMSBuilderError>
Build a ZeroKMSWithClientKey client.
This is only available after calling with_client_key.
§impl<C, K> ZeroKMSBuilder<C, WithKeyProvider<K>>
impl<C, K> ZeroKMSBuilder<C, WithKeyProvider<K>>
pub async fn build(self) -> Result<ZeroKMSWithClientKey<C>, ZeroKMSBuilderError>
pub async fn build(self) -> Result<ZeroKMSWithClientKey<C>, ZeroKMSBuilderError>
Build a ZeroKMSWithClientKey client by loading the key from the provider.
This is an async method because the key provider may need to perform I/O.
Auto Trait Implementations§
impl<C, ClientKeyState> Freeze for ZeroKMSBuilder<C, ClientKeyState>
impl<C, ClientKeyState> RefUnwindSafe for ZeroKMSBuilder<C, ClientKeyState>where
C: RefUnwindSafe,
ClientKeyState: RefUnwindSafe,
impl<C, ClientKeyState> Send for ZeroKMSBuilder<C, ClientKeyState>
impl<C, ClientKeyState> Sync for ZeroKMSBuilder<C, ClientKeyState>
impl<C, ClientKeyState> Unpin for ZeroKMSBuilder<C, ClientKeyState>
impl<C, ClientKeyState> UnsafeUnpin for ZeroKMSBuilder<C, ClientKeyState>where
C: UnsafeUnpin,
ClientKeyState: UnsafeUnpin,
impl<C, ClientKeyState> UnwindSafe for ZeroKMSBuilder<C, ClientKeyState>where
C: UnwindSafe,
ClientKeyState: UnwindSafe,
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<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more