Redact

License Latest version Latest Docs downloads-badge

API docs

A simple library for keeping secrets out of logs.

Redact provides a wrapper that prevents secrets from appearing in logs.

```rust use redact::Secret;

let encryptionkey = Secret::new("hello world"); asserteq!("[REDACTED &str]", format!("{encryption_key:?}")) ```

The underlying secret contained within the wrapper can only be accessed using the [exposesecret][Secret::exposesecret] method or [expose_secret] function[^1].

```rust use redact::Secret;

let encryptionkey = Secret::new("hello world"); asserteq!("hello world", *encryptionkey.exposesecret()) ```

The Secret type doubles as a useful documentation tool. Documenting values maintainers should be careful with.

```rust use redact::Secret;

[derive(Debug)] // Safe since Debug is not able to "see" our Secrets

struct Payment { // The recipient is PII so we don't want it to appear in logs recipient: Secret, // It's okay for the amount to appear in logs so we don't mark it with Secret amount: u64, } ```

Serde support

For serde support ensure the serde feature is enabled in your Cargo.toml.

toml redact = { version = "0.0.11", features = ["serde"] }

Deserialize works as expected, transparently deserializing the enclosed secret.

Since serialization can expose the enclosed secret it is only possible to implement Serialize "with" [expose_secret].

```rust use redact::{Secret, expose_secret}; use serde::{Serialize, Deserialize};

[derive(Serialize, Deserialize)]

struct Payment { #[serde(serializewith = "exposesecret")] recipient: Secret, amount: u64, } ```

Comparison with alternatives

secrecy

Secrecy was the original inspiration for this crate and it has a very similar API.

One significant difference is that secrecy requires that all secrets implement [Zeroize] so that it can cleanly wipe secrets from memory after they are dropped. This unfortunately limits the types of values that secrecy can wrap in a Secret since every type has to be aware of Zeroize.

Redact relaxes this requirement, allowing all types to be Secrets. If you need zeroization consider secrecy.

secrets

Secrets provides even stronger memory protection than secrecy using [mlock(2)]/[mprotect(2)] among other things. If you need strong memory protection before and after a Secret is dropped consider secrets.

[Default], [Hash], [Copy], [Clone], [Ord], [PartialOrd], [Eq], [PartialEq], [std::ops::Add], [std::ops::AddAssign], [std::ops::BitAnd], [std::ops::BitAndAssign], [std::ops::BitOr], [std::ops::BitOrAssign], [std::ops::BitXor], [std::ops::BitXorAssign], [std::ops::Div], [std::ops::DivAssign], [std::ops::Mul], [std::ops::MulAssign], [std::ops::Rem], [std::ops::RemAssign], [std::ops::Shl], [std::ops::ShlAssign], [std::ops::Shr], [std::ops::ShrAssign], [std::ops::Sub], [std::ops::SubAssign], [std::ops::Neg] and [std::ops::Not]