docs.rs failed to build secure-gate-0.2.2
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build:
secure-gate-0.7.0-rc.14
secure-gate
A zero-overhead, no_std-compatible secret wrapper with automatic zeroization.
Key Features Summary
secure-gate is designed for seamless, safe secret handling with zero runtime overhead when features are disabled. Core highlights:
- Auto-Gating: Switches between
SecretBox<T>+ zeroization (defaultzeroizefeature) and plainBox<T>fallback for minimal builds—no code changes required. - No-Std Native: Full
no_std+allocsupport for embedded systems. - Safe & Ergonomic: All public API in 100% safe Rust;
secure!macro for quick construction; aliases likeSecurePassword(immutable default),SecurePasswordMut(mutable opt-in), andSecureKey32. - Redacted & Zeroized: Automatic
Debugredaction ("[REDACTED]"); best-effort zeroization on drop/mutation viazeroize. - Serde-Ready: Opt-in serialization of secrets (explicitly exposes the secret in serialized form, e.g., JSON strings; protect output bytes appropriately).
- Fuzz-Hardened: 6 libFuzzer targets running 360 CPU minutes nightly—all pass with no crashes/leaks after thousands of hours.
Installation
Add this to your Cargo.toml:
[]
= "0.2.1"
Usage
use ;
let password: SecurePassword = "hunter2".into; // Immutable default, zeroized on drop
let key = new; // fixed-size key
let token = new; // dynamic buffer
// Scoped mutation (preferred for mutable cases)
let mut pw_mut: SecurePasswordMut = new;
pw_mut.expose_mut.expose_secret_mut.push_str;
pw_mut.finish_mut; // reduce excess capacity via shrink_to_fit (best-effort; no scrub of freed memory)
// Extraction (use sparingly)
let bytes: = token.into_inner; // original zeroized immediately
Fuzzing Configuration
| Target | Description | Runtime per CI run |
|---|---|---|
expose |
Memory access + finish_mut |
60 minutes |
clone |
init_with, into_inner, scoped zeroization |
60 minutes |
serde |
JSON + bincode deserialization from untrusted input | 60 minutes |
parsing |
FromStr parsing |
60 minutes |
debug |
Debug redaction verification |
60 minutes |
mut |
Unbounded expose_mut() mutation stress |
60 minutes |
- 6 libFuzzer targets
- 360 CPU minutes per nightly run (6 × 60 min)
- Runs on GitHub Actions (ubuntu-latest, nightly toolchain)
-rss_limit_mb=4096,-max_total_time=3600,-timeout=60- Artifacts uploaded on every run
- All targets currently pass with no crashes
Dependencies
[]
= { = "0.10.3", = true, = false }
= { = "1.8", = true, = false, = ["alloc", "zeroize_derive"] }
= { = "1.0", = ["derive"], = true }
Features
| Feature | Effect |
|---|---|
zeroize |
Enables SecretBox<T> + zeroization on drop (default) |
serde |
Adds Serialize / Deserialize impls |
unsafe-wipe |
Opt-in fast zeroization for Secure<String> (no allocation, preserves len/cap; requires zeroize). Disables #![forbid(unsafe_code)] for this path—safe usage (only overwrites used buffer with zeros; null bytes valid UTF-8). Use for performance-critical secrets; stick to safe path otherwise. |
full |
Enables zeroize + serde + unsafe-wipe |
Zeroization Guarantees
Secure<T> provides best-effort memory zeroization on drop/mutation via the zeroize crate:
- What It Does: Explicitly overwrites secret bytes (up to
.len()for dynamic types likeVec/String) using volatile operations that resist compiler optimization. - Platform Coverage: Works on all stable Rust targets (x86, ARM, RISC-V, etc.) via portable intrinsics. No guarantees against hardware leaks (e.g., cache side-channels)—use constant-time primitives alongside.
- Limitations: Only affects the wrapped value; doesn't secure against copies, logs, or kernel dumps. For full protection, avoid extraction (
into_inner) and use scopedexpose_mut(). - finish_mut: After mutations, call this to reduce excess capacity (for
Vec<u8>,String) viashrink_to_fit(). This is best-effort—some allocators may not shrink—and does not overwrite freed memory (old secrets may persist until allocator/OS reuse). Zeroization on drop still covers only the used portion (up to.len()). - Dynamic Container Caveats: For growable types like
Vec<u8>orString, safe Rust cannot zero the full historical capacity (e.g., aftertruncateor realloc). Only the current slice up to.len()is overwritten on drop. Avoid patterns like filling a large buffer with secrets then truncating to small length—opt for fixed-size where possible or explicitly zero excess viaexpose_mut().fill(0)before shrinking. - Unsafe-Wipe Fast Path: When enabled,
Secure<String>usesunsafefor zero-allocation wiping (preserves len/cap)—safe for used buffer only. Null bytes are valid UTF-8; no invariants broken. Opt-in for performance (e.g., high-frequency secrets); safe path used otherwise (allocates temp zeros). - Fallback Mode: Disabled without
zeroizefeature—treat as plainBox<T>.
For details, see zeroize docs.
Contribution
Contributions welcome! Please submit PRs with tests/fuzz targets.
License
Licensed under MIT OR Apache-2.0