sosecrets-rs 0.1.0

A simple `Secret` wrapper type that reveals the secret at most `MEC: typenum::Unsigned` times with compile time guarantees.
Documentation

sosecrets-rs

Secrets Management crate with

  1. type level and compile-time guarantees and
  2. each references corresponding to each secrets can only be exposed or revealed under a lexical scope with an invariant lifetime and
  3. it is only exposed under an identifiable lexical scope and
  4. with an invariant lifetime.

It is similar to the secrecy crate but with type level and compile-time guarantees that the Secret<T, MEC, EC> value is not ’exposed’ more than MEC number of times.

It makes use of the typenum crate for all its compile-time guarantees.

Features

  • Exposure Control: Secret values can only be exposed a limited number of times, preventing unintentional information leaks. This is guaranteed at compile time. Secrets are exposed and available for use with an invariant lifetime, identifiable with a clear lexical scope.
  • Zeroization: If configured with the "zeroize" feature, secrets are zeroized upon dropping them.
  • Cloneable Secrets: With the "cloneable-secret" feature, Secret values can be cloned if the underlying type, T, implements the CloneableSecret trait.
  • Debugging Secrets: The "debug-secret" feature enables the debugging of Secret values if the underlying type, T, implements the DebugSecret trait.

Usage Example

use sosecrets_rs::{
  prelude::*,
  traits::ExposeSecret,
};
use typenum::U2;

// Define a secret with a maximum exposure count of 2
let secret = Secret::<_, U2>::new("my_secret_value".to_string());

// Expose the secret and perform some operations with the exposed value; secret has been exposed once: `EC` = 1, `MEC` = 2;
let (next_secret, exposed_value) = secret.expose_secret(|exposed_secret| {
    // `exposed_secret` is only 'available' from the next line -------
    assert_eq!(&*exposed_secret.as_str(), "my_secret_value"); //     ^
    // Perform operations with the exposed value                     |
    // ...                                                           v
    // to this line... -----------------------------------------------
});

// Expose the secret again and perform some operations with the exposed value; secret has been exposed once: `EC` = 2, `MEC` = 2;
let (next_secret, exposed_value) = next_secret.expose_secret(|exposed_secret| {
    assert_eq!(&*exposed_secret.as_str(), "my_secret_value");
    // Perform operations with the exposed value
    // ...
});

// **Try** to expose the secret again and perform some operations with the exposed value; secret has been exposed once: `EC` = 3, `MEC` = 2;
// The following when uncommented is uncompilable.
// let (next_secret, exposed_value) = next_secret.expose_secret(|exposed_secret| {
//     assert_eq!(&*exposed_secret.as_str(), "my_secret_value");
//     // Perform operations with the exposed value
//     // ...
// });

See more at the examples directory.

Features Configuration

To enable features, you can include them in your Cargo.toml:

[dependencies]
sosecrets-rs = { version = "x.x.x", features = ["zeroize", "cloneable-secret", "debug-secret"] }

Modules

  • prelude: Module for easily importing common items.

Traits

  • ExposeSecret: Trait for safely exposing secrets with a limited exposure count.
  • CloneableSecret: Trait for cloneable secrets.
  • DebugSecret: Trait for debuggable secrets.

Minimum Supported Rust version

The crate currently requires Rust 1.70. I have no intent of increasing the compiler version requirement of this crate beyond this. However, this is only guaranteed within a given minor version number.

Tests

Run

bash scripts/tests-all-features.sh

License

Licensed under

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the MIT license, without any additional terms or conditions.

Credits

CAD97