{"id":13998154,"url":"https://github.com/eopb/redact","last_synced_at":"2025-10-05T18:50:40.481Z","repository":{"id":65486370,"uuid":"584904958","full_name":"eopb/redact","owner":"eopb","description":" A simple library for keeping secrets out of logs","archived":false,"fork":false,"pushed_at":"2024-09-08T10:29:33.000Z","size":86,"stargazers_count":37,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-26T06:23:01.110Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://crates.io/crates/redact","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eopb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-03T20:23:18.000Z","updated_at":"2025-03-04T18:41:59.000Z","dependencies_parsed_at":"2023-10-19T23:21:28.175Z","dependency_job_id":"5281c00b-6d84-40c8-ad65-e31ed637928f","html_url":"https://github.com/eopb/redact","commit_stats":{"total_commits":44,"total_committers":3,"mean_commits":"14.666666666666666","dds":"0.18181818181818177","last_synced_commit":"b83dd96aff5f7e913f039ff234ab8f5b63214a58"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eopb%2Fredact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eopb%2Fredact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eopb%2Fredact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eopb%2Fredact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eopb","download_url":"https://codeload.github.com/eopb/redact/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252526997,"owners_count":21762603,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T19:01:26.046Z","updated_at":"2025-10-05T18:50:35.427Z","avatar_url":"https://github.com/eopb.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Redact\n\n[![License](https://img.shields.io/crates/l/redact.svg)](https://crates.io/crates/redact)\n[![Latest version](https://img.shields.io/crates/v/redact.svg)](https://crates.io/crates/redact)\n[![Latest Docs](https://docs.rs/redact/badge.svg)](https://docs.rs/redact/)\n[![downloads-badge](https://img.shields.io/crates/d/redact.svg)](https://crates.io/crates/redact)\n\n[API docs](https://docs.rs/redact/)\n\nA simple library for keeping secrets out of logs.\n\nRedact provides a wrapper that prevents secrets from appearing in logs.\n\n```rust\nuse redact::Secret;\n\nlet encryption_key = Secret::new(\"hello world\");\nassert_eq!(\"[REDACTED \u0026str]\", format!(\"{encryption_key:?}\"))\n```\n\nThe underlying secret contained within the wrapper can only be accessed using the [expose_secret][Secret::expose_secret] method or [expose_secret] function[^1].\n\n```rust\nuse redact::Secret;\n\nlet encryption_key = Secret::new(\"hello world\");\nassert_eq!(\"hello world\", *encryption_key.expose_secret())\n```\n\nThe `Secret` type doubles as a useful documentation tool.\nDocumenting values maintainers should be careful with.\n\n```rust\nuse redact::Secret;\n\n#[derive(Debug)] // Safe since Debug is not able to \"see\" our `Secret`s\nstruct Payment {\n    // The recipient is PII so we don't want it to appear in logs\n    recipient: Secret\u003cString\u003e,\n    // It's okay for the amount to appear in logs so we don't mark it with `Secret`\n    amount: u64,\n}\n```\n\n## Serde support\n\nFor serde support ensure the serde feature is enabled in your `Cargo.toml`.\n\n```toml\nredact = { version = \"0.1\", features = [\"serde\"] }\n```\n\n`Deserialize` works as expected, transparently deserializing the enclosed secret.\n\nSince serialization can expose the enclosed secret it is only possible to implement `Serialize` \"with\" [expose_secret].\n\n```rust\nuse redact::{Secret, expose_secret};\nuse serde::{Serialize, Deserialize};\n\n#[derive(Serialize, Deserialize)]\nstruct Payment {\n    #[serde(serialize_with = \"expose_secret\")]\n    recipient: Secret\u003cString\u003e,\n    amount: u64,\n}\n```\n\nIf you would like to implement `Serialize` without exposing the `Secret` see [serde::redact_secret].\n\n## Zeroizing `Secret`s\n\n`redact` does not require `Secret`s to be [`Zeroize`][::zeroize::Zeroize]able but does allow `Secret`s to be `Zeroize`d when the contained secret is `Zeroize`able.\nTo be able to `Zeroize` `Secret`s, enable `zeroize` in your `Cargo.toml`.\n\n```toml\nredact = { version = \"0.1\", features = [\"zeroize\"] }\nzeroize = \"1\"\n```\n\nOnce enabled, it is possible zeroize secrets.\n\n```rust\n# use redact::Secret;\nuse zeroize::Zeroize;\n\n\nfn main() {\n    let mut secret = Secret::new(\"hunter2\".to_owned());\n\n    // [ ... ] use secret here\n\n    // Now that we're done using the secret, zero it out.\n    secret.zeroize();\n    # assert_ne!(*secret.expose_secret(), \"hunter2\")\n}\n```\n\nIf you would like your `Secret` to be automatically `Zeroize`d when it is no longer being used,\nconsider wrapping your `Secret` in [`Zeroizing`][::zeroize::Zeroizing] which will `Zeroize` your secret when it is [`Drop`]ed\n\n```rust\n# use redact::Secret;\nuse zeroize::Zeroizing;\n\n\nfn main() {\n    let mut secret = Zeroizing::new(Secret::new(\"hunter2\".to_owned()));\n\n    // [ ... ] use secret here\n\n    // The secret is automatically zeroed out at the end of the scope when it is dropped\n}\n```\n\n## Comparison with alternatives\n\n### [secrecy](https://docs.rs/secrecy/latest/secrecy/)\n\n[Secrecy](https://crates.io/crates/secrecy) was the original inspiration for this crate and it has a similar API.\n\nOne significant difference is that secrecy requires that all secrets implement [`Zeroize`](https://docs.rs/secrecy/latest/secrecy/trait.Zeroize.html) so that it can cleanly wipe secrets from memory after they are dropped.\nThis unfortunately limits the types of values that secrecy can wrap in a `Secret` since every type has to be aware of `Zeroize`.\n\nRedact relaxes this requirement, allowing all types to be `Secret`s.\nWhen zeroizing is required, consider the techniques [above](#zeroizing-secrets).\n\n### [secrets](https://docs.rs/secrets/latest/secrets/)\n\n[Secrets](https://crates.io/crates/secrets) provides even stronger memory protection than [secrecy](#secrecy) using [`mlock(2)`]/[`mprotect(2)`] among other things.\nIf you need strong memory protection before and after a `Secret` is dropped consider [secrets](https://crates.io/crates/secrets).\n\n[`mlock(2)`]: https://man7.org/linux/man-pages/man2/mlock.2.html\n[`mprotect(2)`]: https://man7.org/linux/man-pages/man2/mprotect.2.html\n\n[^1]: [Secret] will assume that it is safe to expose its secret to its contained types implemenations of \n[Default],\n[Hash],\n[Copy],\n[Clone],\n[Ord],\n[PartialOrd],\n[Eq],\n[PartialEq],\n[std::ops::Add],\n[std::ops::AddAssign],\n[std::ops::BitAnd],\n[std::ops::BitAndAssign],\n[std::ops::BitOr],\n[std::ops::BitOrAssign],\n[std::ops::BitXor],\n[std::ops::BitXorAssign],\n[std::ops::Div],\n[std::ops::DivAssign],\n[std::ops::Mul],\n[std::ops::MulAssign],\n[std::ops::Rem],\n[std::ops::RemAssign],\n[std::ops::Shl],\n[std::ops::ShlAssign],\n[std::ops::Shr],\n[std::ops::ShrAssign],\n[std::ops::Sub],\n[std::ops::SubAssign],\n[std::ops::Neg] and\n[std::ops::Not]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feopb%2Fredact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feopb%2Fredact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feopb%2Fredact/lists"}