Bad Passwords Docs

Bad Passwords provides registration, login, token validation, and logout endpoints for delegated password verification backed by a remote Argon2 hash.

API Docs

The API accepts either HTML form posts or JSON requests. For API use, send Accept: application/json. For JSON bodies, also send Content-Type: application/json.

Contents

Endpoint Summary
POST /register Register a user after proving the supplied password matches the remote Argon2 hash.
POST /login Verify a password against the current remote hash and issue an RS256-signed JWT.
POST /validate Validate a JWT signature and return the decoded payload when the token is valid.
DELETE /logout Rotate the user's token version to invalidate previously issued tokens.

POST /register

Field Required Description
email yes Email address to register. Must be unique.
password_hash_url yes URL that returns a plaintext Argon2 password hash.
password yes Plaintext password used to prove the remote hash belongs to the registrant.

Example JSON request:

{
  "email": "user@example.com",
  "password_hash_url": "https://example.com/hash.txt",
  "password": "correct horse battery staple"
}

Successful JSON response:

{
  "email": "user@example.com",
  "password_hash_url": "https://example.com/hash.txt"
}

Error JSON response:

{
  "error": "Could not verify the password hash URL."
}

Back to contents


POST /login

Field Required Description
email yes Registered email address.
password yes Plaintext password to verify against the current remote Argon2 hash.

Example JSON request:

{
  "email": "user@example.com",
  "password": "correct horse battery staple"
}

Successful JSON response:

{
  "token": "JWT_TOKEN_HERE",
  "token_type": "Bearer",
  "email": "user@example.com"
}

Decoded JWT payload fields:

Claim Description
sub User email.
iss Value of JWT_ISSUER.
iat Issued-at timestamp.
ver Current per-user token version.
exp Expiry timestamp, one hour after issue.

Error JSON response:

{
  "error": "Invalid email or password."
}

Back to contents


POST /validate

Provide the JWT either as a JSON token field or in the Authorization: Bearer <token> header.

Field Required Description
token yes, unless sent as Bearer token JWT to validate with the configured public key.

Example JSON request:

{
  "token": "JWT_TOKEN_HERE"
}

Successful JSON response:

{
  "valid": true,
  "payload": {
    "sub": "user@example.com",
    "iss": "bad-passwords-dev",
    "iat": 1710000000,
    "exp": 1710003600
  }
}

Error JSON response:

{
  "valid": false,
  "error": "Invalid token."
}

Back to contents


DELETE /logout

Authenticate either with a valid Bearer token or with JSON credentials. Successful logout rotates the user's token version, invalidating all previously issued tokens.

Field Required Description
username or email yes, unless sent as Bearer token Registered email address for credential-based logout.
password yes, unless sent as Bearer token Plaintext password to verify before rotating the token version.

Example JSON request:

{
  "username": "user@example.com",
  "password": "correct horse battery staple"
}

Successful JSON response:

{
  "success": true,
  "email": "user@example.com"
}

Error JSON response:

{
  "error": "Invalid token or credentials."
}

Back to contents