secret-fmt
Accidental logging of PII (emails, IP addresses) or secrets (API keys, passwords) is a massive security liability.
secret-fmt provides a tiny, zero-dependency #![no_std] wrapper type called Secret<T> that prevents accidental logging by overriding Debug and Display to emit "[REDACTED]".
It has zero trait bounds, meaning you can wrap any third-party type instantly without having to write boilerplate.
Usage
use ;
// 1. Wrap your sensitive data
let my_secret: = "super_secret_api_token".to_string.into;
// 2. Accidental logging is safe!
println!; // Prints: User token is: [REDACTED]
println!; // Prints: Debug token is: [REDACTED]
// 3. Log inline references safely without ownership
let token = "sensitive_data";
println!; // Prints: [REDACTED]
// 4. Access the data only when you actually need it
let actual_token: &String = my_secret.as_inner;
assert_eq!;
Serde Safety (Optional Feature)
Unlike other crates, Secret<T> intentionally does not implement Serialize by default.
If a user serializes a database struct and the password field writes "[REDACTED]", it causes data destruction. Instead, secret-fmt forces you to be explicit about how the data leaves your system using #[serde(serialize_with)].
In Cargo.toml:
[]
= { = "0.1", = ["serde"] }
#
#
#
#
Why not secrecy?
The secrecy crate is fantastic, but it enforces the Zeroize trait on everything it wraps to clear memory on drop. If you are dealing with types from external crates (like reqwest::HeaderValue), you have to write boilerplate wrappers to use secrecy.
Secret makes no attempt to clear memory—it focuses exclusively on stopping string/log/JSON leakage. Because it drops the Zeroize requirement, it works instantly on any type out of the box with zero dependencies.