Skip to main content

Crate zero_secrets

Crate zero_secrets 

Source
Expand description

Simple lightweight secret wrappers that zeroize on drop and prevent accidental logging. Built on RustCrypto zeroize

This crate provides three owned wrappers around in-memory secret material, backed by the RustCrypto zeroize crate:

  • SecretString owns a heap String (e.g. NKEY seeds, .creds text, invite/recovery codes, base64-encoded credentials).
  • SecretBytes owns a heap Vec<u8> (e.g. decrypted plaintext buffers, credential blobs, message bodies that may contain secrets).
  • SecretArray<N> owns a fixed-size stack [u8; N] (e.g. X25519 private seeds, AEAD keys, shared secrets — typically [u8; 32]).

§Guarantees

Every wrapper:

  1. Zeroizes its backing storage on Drop (heap allocation contents for the string/bytes wrappers, the stack bytes for SecretArray).
  2. Redacts Debug. Display is not implemented to prevent {} formatting. Secret contents or length are not printed.
  3. Produces an independently owned value on Clone — a deep copy with its own allocation (for the heap types) whose own Drop also zeroizes. This holds for clones moved into async blocks/tasks.

§Ownership contract

  • Borrow in: callers wrap only when this code takes ownership of a secret. Code that merely reads a secret should accept &str / &[u8].
  • Wrap on ownership: construct via new or the From impls when an owned secret enters the crate that owns it.
  • Borrow for use: read through expose_secret (returns &str / &[u8]); the borrow never escapes the wrapper.
  • Plain owned out: when ownership must leave the library, use the #[must_use] extractors (into_string, into_vec, into_inner). These return the plain owned value and intentionally do not zeroize the moved-out value — the caller then owns leak prevention. Their inputs are consumed, so no wrapped copy lingers.

These wrappers are designed to be internal to your crate, used to protect private owned fields. Keep Secret* types out of your public API: accept &str / &[u8] in inputs, and return borrowed accessors via expose_secret for normal use. Use plain owned extractors only when ownership must leave the boundary. serde::Serialize / Deserialize are intentionally not implemented. If serializing is needed, it should be in targeted, auditable call-sites.

Structs§

SecretArray
An owned, zeroizing wrapper around a fixed-size [u8; N] stack array.
SecretBytes
An owned, zeroizing wrapper around a Vec<u8>.
SecretString
An owned, zeroizing wrapper around a String.