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 ==.