pub struct Sensitive<T: Zeroize>(/* private fields */);Expand description
A secret value, redacted in Debug/Display and zeroized on drop.
Never derive or implement Serialize on a type embedding this — that is
the point: Sensitive deliberately has no Serialize impl, so a
container that tries to derive one over a field of this type fails to
compile instead of silently emitting the raw secret.
Deserializing (reading a secret in from TOML/env/CLI) is fine and
supported via serde’s Deserialize — only the write-out direction is
closed.
Implementations§
Source§impl<T: Zeroize> Sensitive<T>
impl<T: Zeroize> Sensitive<T>
Sourcepub const fn expose(&self) -> &T
pub const fn expose(&self) -> &T
Returns the wrapped value. The explicit name makes every read site
grep-able (rg '\.expose\(') and visibly intentional.
The borrow this returns stays covered by Sensitive’s redaction and
zeroize-on-drop, but nothing stops a call site from cloning it out —
e.g. handing an owned String to a client that then holds its own
untracked, un-zeroized copy for as long as that client lives. The LLM
provider configs and constructors hold the key wrapped for their whole
lifetime instead (#1277); see the provider crates. The general risk
remains for any other call site that reaches for expose and clones
the result into a plain, unwrapped copy.
Sourcepub const fn expose_secret(&self) -> &T
pub const fn expose_secret(&self) -> &T
Alias for Self::expose, matching the secrecy crate’s accessor
name for call sites migrating between the two wrappers. Same
past-this-point caveat: see Self::expose.
Source§impl Sensitive<String>
impl Sensitive<String>
Sourcepub fn filter_nonempty(opt: Option<&Self>) -> Option<Self>
pub fn filter_nonempty(opt: Option<&Self>) -> Option<Self>
Treats an empty string as “not configured”.
Config loading routinely needs to turn an optional secret field into
None when it’s merely present-but-empty — the wire encoding a
shipped manifest’s ConfigMap uses for “unset” — before ever making a
request with it. That check has to read the wrapped value, so this is
the one sanctioned emptiness peek on a Sensitive<String> outside a
request path; every other read site should reach for Self::expose
only at the point where the secret is actually used (e.g. an auth
header), not to inspect or branch on it ahead of time.
Returns None for None or Some wrapping "", otherwise clones
opt’s value into a fresh, independently-owned Some.
Trait Implementations§
Source§impl<'de, T> Deserialize<'de> for Sensitive<T>where
T: Deserialize<'de> + Zeroize,
impl<'de, T> Deserialize<'de> for Sensitive<T>where
T: Deserialize<'de> + Zeroize,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl FromStr for Sensitive<String>
impl FromStr for Sensitive<String>
Source§fn from_str(s: &str) -> Result<Self, Self::Err>
fn from_str(s: &str) -> Result<Self, Self::Err>
Wraps the raw string so a clap Args/Parser field declared
Sensitive<String> parses straight off the CLI/env value — clap infers
a value parser from FromStr for any type that isn’t a ValueEnum.
Deliberately concrete on String rather than a blanket
impl<T: FromStr>: a blanket impl registers Sensitive<_> as a
FromStr candidate for every open inference variable in every
downstream crate, which silently reshapes unrelated .parse() inference
(it drove polyc-agent’s env parsing to a LazyLock<String> fallback
that no longer type-checked). Every edge wraps a String, so a concrete
impl carries the full feature with none of the inference blast radius.
Source§type Err = Infallible
type Err = Infallible
Auto Trait Implementations§
impl<T> Freeze for Sensitive<T>where
T: Freeze,
impl<T> RefUnwindSafe for Sensitive<T>where
T: RefUnwindSafe,
impl<T> Send for Sensitive<T>where
T: Send,
impl<T> Sync for Sensitive<T>where
T: Sync,
impl<T> Unpin for Sensitive<T>where
T: Unpin,
impl<T> UnsafeUnpin for Sensitive<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for Sensitive<T>where
T: 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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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 more