Skip to main content

Secret

Struct Secret 

Source
pub struct Secret {
    pub account_id: Uuid,
    pub secret: HashedValue,
}
Expand description

A cryptographically secure secret (password) bound to a specific user account.

This type represents a hashed password or other sensitive authentication data that is cryptographically bound to a specific account through its unique identifier. The secret is automatically hashed using the Argon2 algorithm when created, ensuring that plaintext passwords are never stored in memory or persistent storage.

§Security Properties

  • Irreversible hashing: Plaintext secrets cannot be recovered from the hash
  • Unique salting: Each secret has a cryptographically random salt
  • Timing attack resistance: Verification operations run in constant time
  • Account binding: Secrets are tied to specific account IDs for additional security

§Usage in Authentication Flows

Secrets are typically created during user registration and verified during login:

use axum_gate::secrets::Secret; use axum_gate::hashing::argon2::Argon2Hasher; use axum_gate::verification_result::VerificationResult;
use axum_gate::accounts::AccountInsertService;
use uuid::Uuid;

// During registration
let account_id = Uuid::now_v7();
let user_password = "user_entered_password";
let hasher = Argon2Hasher::new_recommended().unwrap();

let secret = Secret::new(&account_id, user_password, hasher.clone())?;

// During login verification
let login_attempt = "user_entered_password";
match secret.verify(login_attempt, hasher)? {
    VerificationResult::Ok => {
        // Grant access - password is correct
        println!("Authentication successful");
    },
    VerificationResult::Unauthorized => {
        // Deny access - password is incorrect
        println!("Authentication failed");
    }
}

§Storage Considerations

Secrets should be stored separately from account data for enhanced security:

  • Use dedicated secret repositories (SecretRepository)
  • Consider separate databases for account metadata vs. authentication secrets
  • Implement appropriate access controls on secret storage
  • Regular backup and recovery procedures for authentication data

§Performance Notes

Secret hashing and verification are intentionally computationally expensive operations (typically 100-500ms) to resist brute-force attacks. Consider:

  • Implementing rate limiting on authentication endpoints
  • Using async/await to prevent blocking during verification
  • Caching verification results appropriately (with security considerations)

The account_id must correspond to a valid account in an AccountRepository to create a correct secret.

Fields§

§account_id: Uuid

The account id that this secret belongs to.

§secret: HashedValue

The actual secret.

Implementations§

Source§

impl Secret

Source

pub fn new<Hasher: HashingService>( account_id: &Uuid, plain_secret: &str, hasher: Hasher, ) -> Result<Self>

Creates a new secret by hashing the provided plaintext password.

This method takes a plaintext secret (typically a user password) and creates a new Secret instance with the secret cryptographically hashed using the provided hashing service. The original plaintext is never stored.

§Parameters
  • account_id: The unique identifier of the account this secret belongs to
  • plain_secret: The plaintext password or secret to be hashed
  • hasher: The hashing service implementation (typically Argon2Hasher)
§Security
  • The plaintext secret is immediately hashed and the original value is dropped
  • A cryptographically secure random salt is generated for each secret
  • The resulting hash is computationally infeasible to reverse
§Errors

Returns an error if the hashing operation fails, which may occur due to:

  • Insufficient system resources for the hashing algorithm
  • Invalid parameters in the hashing service configuration
  • System-level cryptographic failures
§Example
use axum_gate::secrets::Secret; use axum_gate::hashing::argon2::Argon2Hasher;
use uuid::Uuid;

let account_id = Uuid::now_v7();
let password = "user_password_123";
let hasher = Argon2Hasher::new_recommended().unwrap();

let secret = Secret::new(&account_id, password, hasher)?;
// The plaintext password is now securely hashed and cannot be recovered
Source

pub fn from_hashed(account_id: &Uuid, hashed_secret: &HashedValue) -> Self

Creates a secret from an already-hashed value.

This constructor is used when you already have a properly hashed secret value, typically when loading secrets from persistent storage or when migrating from other authentication systems.

§Parameters
  • account_id: The unique identifier of the account this secret belongs to
  • hashed_secret: A previously computed hash value from a compatible hashing algorithm
§Security Warning

This method bypasses the normal hashing process and directly uses the provided hash. Ensure that:

  • The hash was created using a secure, compatible algorithm (preferably Argon2)
  • The hash includes proper salting
  • The source of the hash is trusted and verified
§Use Cases
  • Loading secrets from database storage
  • Migrating authentication data between systems
  • Testing with pre-computed hash values
  • Bulk operations where hashing has already been performed
§Example
use axum_gate::secrets::Secret; use axum_gate::hashing::argon2::Argon2Hasher; use axum_gate::hashing::HashedValue;
use uuid::Uuid;

// Typically this hash would come from your database
let account_id = Uuid::now_v7();
let hasher = Argon2Hasher::new_recommended().unwrap();
let original_secret = Secret::new(&account_id, "password", hasher.clone())?;
let stored_hash = &original_secret.secret;

// Reconstruct the secret from the stored hash
let reconstructed = Secret::from_hashed(&account_id, stored_hash);
Source

pub fn verify<Hasher: HashingService>( &self, plain_secret: &str, hasher: Hasher, ) -> Result<VerificationResult>

Verifies a plaintext secret against the stored hash.

This method performs constant-time verification of a plaintext secret (typically a password entered by a user) against the stored cryptographic hash. The verification process is designed to be resistant to timing attacks.

§Parameters
  • plain_secret: The plaintext secret to verify (e.g., user-entered password)
  • hasher: The hashing service to use for verification (must be compatible with the stored hash)
§Returns
§Security Properties
  • Constant-time operation: Verification takes the same time regardless of correctness
  • No information leakage: Incorrect attempts don’t reveal information about the stored secret
  • Timing attack resistance: Prevents attackers from using timing differences to guess secrets
§Performance

Secret verification is computationally intensive by design (typically 100-500ms) to make brute-force attacks impractical. This is normal and expected behavior for secure password hashing algorithms like Argon2.

§Errors

Returns an error if the verification process fails due to:

  • Incompatible hashing algorithms between creation and verification
  • Corrupted hash data
  • System-level cryptographic failures
§Example
use axum_gate::secrets::Secret; use axum_gate::hashing::argon2::Argon2Hasher; use axum_gate::verification_result::VerificationResult;
use uuid::Uuid;

let account_id = Uuid::now_v7();
let correct_password = "secure_password_123";
let hasher = Argon2Hasher::new_recommended().unwrap();

// Create secret during registration
let secret = Secret::new(&account_id, correct_password, hasher.clone())?;

// Verify during login - correct password
let result = secret.verify(correct_password, hasher.clone())?;
assert_eq!(result, VerificationResult::Ok);

// Verify during login - incorrect password
let result = secret.verify("wrong_password", hasher)?;
assert_eq!(result, VerificationResult::Unauthorized);

Trait Implementations§

Source§

impl Clone for Secret

Source§

fn clone(&self) -> Secret

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Secret

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Secret

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<Secret> for ActiveModel

Source§

fn from(value: Secret) -> Self

Converts to this type from the input type.
Source§

impl Serialize for Secret

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<G1, G2> Within<G2> for G1
where G2: Contains<G1>,

Source§

fn is_within(&self, b: &G2) -> bool