crates.io ↗

iet-auth-basic

feature implementation official

Bcrypt and Argon2 implementations of the password contracts, plus PasswordAuth.

CoreFeaturesIntegrationsStacksTooling
Used byno framework crate yetexamples/htmx-starterexamples/skills-only-appexamples/skills-only-app-task-tracker
iet-auth-basicimplementationPassword hashing and verification
Depends oniet-telemetrycontractiet-corecontractiet-authcontractiet-configcontractiet-config-macroscontract

How to use it

iet-auth-basic turns a login plus password into a verified Principal using bcrypt (the BasicAuth default) or Argon2 (Argon2Auth). You supply a CredentialStore that maps a login to a subject, stored hash, and enabled flag; the crate owns hashing, bounded verification queues, and a same-cost dummy hash so unknown accounts cost the same as known ones. The result implements Authenticate<PasswordCredentials>, which login adapters such as iet-auth-basic-axum drive.

rust
// crates/features/iet-auth-basic/tests/password.rs
use iet_auth::{Authenticate, PasswordCredentials, Secret};
use iet_auth_basic::PasswordAuth;

// `Store: CredentialStore` resolves a login to subject + stored hash + enabled.
// `Verify: PasswordVerifier` checks a password against that hash.
// Build once at startup; the dummy hash uses the same algorithm and cost.
let auth = PasswordAuth::new(Store, Verify, dummy_hash);

for (login, password, allowed) in [
    ("enabled", "correct", true),
    ("enabled", "wrong", false),
    ("disabled", "correct", false),
    ("missing", "correct", false),
] {
    let result = auth
        .authenticate(&PasswordCredentials {
            login: login.into(),
            password: Secret::new(password.into()),
        })
        .await;
    assert_eq!(result.is_ok(), allowed);
}
  • BasicAuth::configured(store, BcryptConfig::default()) and Argon2Auth::configured(store, PasswordConfig) build the verifier and same-cost dummy hash for you.
  • Verification work is bounded; overload returns password.busy or password.queue_timeout rather than queueing without limit.
  • The returned Principal.profile is always None; persona selection is a separate step (iet-auth-profiles).

How it works

authenticate looks the account up through the CredentialStore, verifies the password against the stored hash or the same-cost dummy hash, and only returns a Principal when the account is verified, enabled, and has a non-empty subject.

sequenceDiagram
  participant C as "Caller"
  participant P as "PasswordAuth"
  participant S as "CredentialStore"
  participant V as "PasswordVerifier"
  C->>P: "authenticate PasswordCredentials"
  P->>S: "account login"
  S-->>P: "PasswordAccount or None"
  alt "account present"
    P->>V: "verify password stored hash"
  else "unknown login"
    P->>V: "verify password dummy hash"
  end
  V-->>P: "bool verified"
  P-->>C: "Principal subject profile None"

What it implements

  • Implements iet_auth::PasswordVerifier from iet-auth.
  • Implements iet_auth::PasswordHasher from iet-auth.
  • Implements iet_auth::Authenticate<PasswordCredentials> from iet-auth.

What's inside

Modules

  • src/argon2.rs
  • src/bcrypt.rs
  • src/config.rs
  • src/lib.rs
  • src/password.rs

Public API

(root)

  • type BasicAuth — Default password authentication uses bcrypt. Select Argon2 explicitly via Argon2Auth.
  • type Argon2Auth

argon2

  • struct Argon2Passwords
  • pub fn new(config: config::PasswordConfig) -> AppResult<Self>

bcrypt

  • struct BcryptPasswords
  • pub fn new(config: BcryptConfig) -> AppResult<Self>

config

  • struct BcryptConfig
  • struct PasswordConfig

password

  • struct PasswordAuth
  • pub fn new(store: S, verifier: V, dummy_hash: Secret<String>) -> Self — Dummy hash must use the same algorithm/cost as real account hashes.

Impl map

  • PasswordHasher for Argon2Passwords
  • PasswordVerifier for Argon2Passwords
  • PasswordHasher for BcryptPasswords
  • PasswordVerifier for BcryptPasswords
  • Default for BcryptConfig
  • Authenticate<PasswordCredentials> for PasswordAuth<S, V>
  • CredentialStore for Store
  • PasswordVerifier for Verify

Depends on

External crates: argon2, bcrypt, rand_core, tokio, zeroize

Used by

  • No other framework crate depends on it directly.

In this repository

  • examples/htmx-starter
  • examples/skills-only-app
  • examples/skills-only-app-task-tracker

Source: crates/features/iet-auth-basic