Authentication flow
The vast majority of IBA members (~90%+) sign in with a standard username and password. Google and Facebook login are available too, but they’re an opt-in account-linking feature: a member must first create their account and sign in with username and password before they can connect a Google or Facebook identity.
This page describes all three flows in the order they actually matter: primary username/password login, OAuth login (only for members who linked a provider), and the account-linking flow itself.
Primary login — username + password
This is what nearly every member does, every time.
Key rules
- Password storage — bcrypt hashes only; never plain text.
role_idgates sign-in — see member lifecycle. A member withrole_id = 4(pending email verification) can’t fully sign in;role_id = 2(banned/deleted) is rejected without revealing whether the account exists.- Rate limiting — repeated failed logins are throttled per IP and per username to mitigate brute force.
Two-factor authentication (2FA)
After the password check, members with 2FA enabled must clear a second factor before a session is issued. Two distinct mechanisms exist:
- Email / SMS one-time passcode (OTP) — for regular members who have
opted in (
members.two_fa = 1). - Authenticator-app TOTP — mandatory for the admin account
(
role_id = 1), which never falls through to the OTP path.
When the OTP step applies
The OTP gate fires only when both are true:
members.two_fa = 1(the member opted into 2FA), and- the member hasn’t completed 2FA within the last 8 hours
(
last_loginis empty or older than 480 minutes).
So an opted-in member is challenged at most once per 8-hour window, not on every request.
OTP delivery and verification
Delivery channel is chosen automatically:
- Email only when the member has a verified email but no verified phone.
- Email by request when the client passes
passcodeOption = 'email'and the email is verified. - SMS otherwise — sent to
+<dialing-code><phone>. The SMS provider routes from the UK Twilio number for+44recipients and the US number for everyone else. See SMS dialing code below.
OTP rules
- 6-digit code — randomly generated, stored per member with an attempt counter.
- 10-minute expiry — a code older than 10 minutes is rejected as expired.
- Single-use — a correct code stamps
last_loginand is immediately deleted. - Send throttle — after 4 sends within 10 minutes, further sends are rate-limited.
- Verification lock-out — at 5 validation attempts the stored code is discarded and the member must request a new one.
- Masked recipient — the prompt shows a masked email/phone, never the full value.
SMS dialing code
The SMS recipient is built as +${members.country}${members.phone}.
members.country stores the numeric dialing code (e.g. 1, 44),
not an ISO code — the ISO code lives in members.country_code. A member
whose members.country is 0 (never resolved) would produce an invalid
+0… number and silently receive no SMS; that’s a data-integrity concern
corrected outside the login flow, not a property of this code path.
Admin TOTP (role_id = 1)
The shared admin account must use an authenticator app (TOTP) and is never offered the email/SMS OTP path:
- On first admin login, if TOTP isn’t configured the API returns
requiresTotpSetup; setup returns a QR code plus one-time backup codes. - Subsequent logins return
requiresTotpand require a current TOTP code (or a backup code) to complete sign-in. - TOTP setup, verification, and backup-code use are restricted to
role_id = 1; any other role is rejected.
OAuth login (Google / Facebook)
Available only to members who have already linked a Google or Facebook identity to their account via the account-linking flow below. A member who has never linked a provider can’t sign in via OAuth — the “Sign in with Google / Facebook” buttons return them to the username/password form with a hint to connect a provider first.
The platform deliberately does not auto-create a member from an OAuth identity. A successful OAuth verification with no matching linked member returns the user to the username/password flow.
Account linking (enabling Google / Facebook login)
How a member opts in to OAuth login. Happens inside an authenticated session — the member must already be signed in via username/password.
Linking rules
- One-way link. Linking adds an alternative sign-in path; it does not change the member’s username or password.
- Linked identity is unique. A given Google or Facebook account can be linked to at most one IBA member. Re-using a provider account for a second IBA member is rejected with a 409.
- Either provider, both, or neither. A member can link Google, Facebook, both, or neither — they’re independent toggles.
- Unlinking is supported in account settings; it disables the corresponding OAuth login but doesn’t affect the underlying username/password sign-in.
Token refresh flow
Logout flow
Security considerations
- Token expiry — access tokens expire after 15 minutes, refresh tokens after 7 days.
- HTTPS only — all authentication traffic must use HTTPS.
- Session storage — sessions stored in Redis with automatic expiry.
- Rate limiting — login attempts (both username/password and OAuth) are rate-limited per IP and per account to prevent brute force.
- CSRF protection —
stateparameter used in OAuth flows to prevent CSRF attacks. - No account enumeration — login errors are deliberately generic (“invalid credentials”) and don’t reveal whether a username exists.
- 2FA enforced server-side — there is no header or portal exemption; an opted-in member (or the admin account) must complete the second factor. OTP codes are single-use, expire after 10 minutes, and are both send-throttled and lock-out-protected.