Skip to main content

ZeroKMSBuilder

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:

  1. Explicit URL via with_base_url
  2. CS_ZEROKMS_HOST (or legacy CS_VITUR_HOST) environment variable
  3. Automatically from the token’s services claim

§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, ()>

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, ()>

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

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

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

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

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

Set the maximum number of concurrent requests.

Defaults to 5 if not set.

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>>

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>

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>

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>

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>>

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>
where C: Freeze, ClientKeyState: Freeze,

§

impl<C, ClientKeyState> RefUnwindSafe for ZeroKMSBuilder<C, ClientKeyState>
where C: RefUnwindSafe, ClientKeyState: RefUnwindSafe,

§

impl<C, ClientKeyState> Send for ZeroKMSBuilder<C, ClientKeyState>
where C: Send, ClientKeyState: Send,

§

impl<C, ClientKeyState> Sync for ZeroKMSBuilder<C, ClientKeyState>
where C: Sync, ClientKeyState: Sync,

§

impl<C, ClientKeyState> Unpin for ZeroKMSBuilder<C, ClientKeyState>
where C: Unpin, ClientKeyState: Unpin,

§

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: Rng + ?Sized, Self: FakeBase<U>,

Source§

impl<T> Fake for T

Source§

fn fake<U>(&self) -> U
where Self: FakeBase<U>,

Source§

fn fake_with_rng<U, R>(&self, rng: &mut R) -> U
where R: Rng + ?Sized, Self: FakeBase<U>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> AuthStrategyBounds for T
where T: Send + Sync + 'static,