Skip to main content

Passwords (Argon2id)

IdentSphere uses Argon2id by default and accepts bcrypt for legacy imports. Both algorithms are NIST + OWASP recommended, supported by every major language, and exportable without proprietary lock-in.

Hashing

hash_password(plain) returns an Argon2id hash with the OWASP-recommended parameters baked in (m=64 MiB, t=2, p=4). Hashes look like:

$argon2id$v=19$m=65536,t=2,p=4$randomsalt...$encodedhash...

Verification

verify_password(plain, stored_hash) returns one of three results:

  • Verified::Ok — match against Argon2id.
  • Verified::OkNeedsRehash — match against bcrypt (legacy). Upgrade.
  • Verified::Mismatch — wrong password.

The login handler observes OkNeedsRehash and silently rehashes the user's password to Argon2id in the background. The user never sees the upgrade.

Length policy

OperationMinMax
Register12256
Change password12256
Password reset12256
Login1(none)

The 1-char minimum on login is intentional: existing accounts with short legacy passwords still get to log in (and on success, get rehashed to Argon2id). New passwords always must hit 12 chars.

::: tip Why not enforce composition rules? NIST 800-63B (2024) recommends against composition rules ("must contain a number and a symbol") — they don't measurably improve security and they push users toward predictable variants. We enforce length only. :::

Pre-computed hash lists / breach checking

IdentSphere does NOT integrate with Have I Been Pwned or similar breach databases in v0.1. If you want this, wrap registration / reset with your own pre-validation that calls the HIBP API client-side or server-side.

Rate limiting

The SDK does NOT include a built-in rate limiter on login. Mount your own tower-governor (or similar) layer in front of /v1/auth/login and /v1/auth/password/forgot.

use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer};

let conf = GovernorConfigBuilder::default()
.per_second(2)
.burst_size(5)
.finish()
.unwrap();

let auth_routes = routes::auth::router()
.layer(GovernorLayer { config: Box::leak(Box::new(conf)) });

Migrating from other auth systems

The SDK accepts bcrypt hashes directly. To migrate users:

  1. Export email + bcrypt_hash from the old system.
  2. INSERT INTO IdentSphere.users (email, password_hash, …) with the bcrypt hash in password_hash.
  3. Users log in with their existing passwords; on first login, the SDK rehashes to Argon2id.

The Argon2id verifier accepts both formats — no flag to flip.

Constant-time comparison

Both Argon2id and bcrypt internally use constant-time comparison. The SDK never compares plaintext passwords or hashes with ==.