Skip to Content

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_id gates sign-in — see member lifecycle. A member with role_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_login is 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 +44 recipients 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_login and 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 requiresTotp and 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 protectionstate parameter 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.
Last updated on