Bad Passwords provides registration, login, token validation, and logout endpoints for delegated password verification backed by a remote Argon2 hash.
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.
| 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. |
| Field | Required | Description |
|---|---|---|
| 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."
}
| Field | Required | Description |
|---|---|---|
| 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."
}
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."
}
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."
}