এই ভলিউমে · ভলিউম 02
ব্যবহারকারী
ব্যবহারকারী, ভূমিকা ও RBAC অথেনটিকেশন
বাংলা সারসংক্ষেপ

পাসওয়ার্ড (Argon2id হ্যাশ), ঐচ্ছিক MFA (TOTP), API-এর জন্য Personal Access Tokens। সেশন কুকি HttpOnly, Secure, SameSite=Strict। ব্রুট-ফোর্স প্রতিরোধ: ১০ ব্যর্থ চেষ্টার পর ১৫ মিনিট লক।

Chapter 2.2 — Authentication

1. Purpose

Authentication is the gateway to every other module in travoBooks. This chapter defines how identities are proved — for human users, partner-employee logins, customer self-service accounts, and machine-to-machine API consumers — and how sessions are issued, validated, and revoked. It also defines password policy, multi-factor enrolment, lockout behaviour, and personal-access-token (PAT) lifecycle.

Authorisation — what an authenticated principal is allowed to do — is covered in Chapter 2.1 (Users, Roles & RBAC) and Chapter 2.3 (Permission Catalog).

2. Why it matters in modern travel accounting

A travel-accounting platform sits on top of irreplaceable financial state: a single compromised accountant session can post fraudulent journal entries that take weeks to unwind. The platform also issues real airline tickets — each one a regulated, settled financial obligation with the BSP. Authentication failures translate directly into financial loss, ADM exposure, and customer trust damage.

Industry-specific pressure on auth design: - Agents work from mobile devices on public Wi-Fi. - Mid-office staff at large agencies use shared workstations. - Corporate clients expect SSO into their identity provider. - API integration partners need long-lived, scoped credentials. - IATA / BSP audits require demonstrable identity assurance.

3. Industry relevance

The travoBooks auth model aligns with NIST SP 800-63B Authenticator Assurance Level 2 for staff users handling financial postings, and Level 3 for partner-admin operations (high-impact configuration changes, payouts). Customer self-service accounts default to Level 1 with optional MFA upgrade.

4. Compliance considerations

  • PCI DSS 8.x — strong authentication for all access to systems handling cardholder data (travoBooks does not store PANs, but the gateway-token paths still require strong auth).
  • GDPR Art. 32 — appropriate technical measures including authentication strength proportional to data sensitivity.
  • SOC 2 CC6 — logical access controls; documented authentication mechanisms.
  • IATA Resolution 818g — agent identity controls for IATA-accredited members.
  • Local data-protection laws (Bangladesh DPA, India DPDP, EU GDPR) — record of consent, breach-notification triggers.

5. Business logic

5.1 Authentication factors supported

Factor Type Use
Password (Argon2id) Something you know Primary for human users
TOTP (RFC 6238) Something you have MFA — required for partner_admin, accountant, approver roles
WebAuthn / Passkey Something you have/are Phase 2 — preferred MFA
Email-OTP Something you have Fallback MFA; account recovery
SMS-OTP Something you have Customer self-service MFA
SAML 2.0 / OIDC SSO Federated Corporate partners (Phase 2)
Personal Access Token (PAT) Bearer credential Machine-to-machine API
Mutual TLS (mTLS) Certificate High-value integration partners (Phase 2)

5.2 Password policy

Rule Value
Minimum length 12 characters
Composition No mandatory mix; passphrase encouraged
Breach check Pwned Passwords API (k-anonymity); rejection if found
History Last 12 passwords cannot be reused
Maximum age 365 days (rotation required)
Lockout threshold 5 failed attempts within 15 minutes
Lockout duration Exponential — 1m, 5m, 15m, 1h, 24h
Reset method Email link + MFA confirmation if enrolled
Hashing Argon2id, memory=64MB, time=4, parallelism=2
Pepper Per-deployment secret stored in KMS

Passwords are never logged, returned in API responses, or written to disk outside the hashed password_hash column.

5.3 Session model

Sessions are server-side, identified by an opaque session ID in a __Host-travoBooks-Session cookie.

Attribute Value
Cookie name __Host-travoBooks-Session
Cookie flags HttpOnly; Secure; SameSite=Strict; Path=/
Session ID format 256-bit cryptographically random, base64url-encoded
Session store Redis (per-deployment)
Idle timeout 30 minutes (configurable per partner)
Absolute lifetime 12 hours (re-authentication required after)
Concurrent sessions per user Limited to 5; oldest evicted
Rotation on privilege elevation New session ID issued
Binding IP address (range-tolerant), User-Agent fingerprint, partner_id

Session records also store a risk_score updated by signals (geo change, new device, unusual timing) — high-risk sessions trigger step-up MFA.

5.4 Multi-factor authentication

MFA enrolment is mandatory for: - Any role with is_financial = TRUE (accountant, partner_admin, approver, cashier) - Any user with API key creation permission - Any user in a partner with mfa_required = TRUE policy

MFA enrolment is optional but recommended for all other users.

MFA enrolment flow: 1. User logs in with password. 2. System prompts MFA enrolment (TOTP QR code or WebAuthn registration). 3. User scans QR / registers passkey. 4. User enters one current OTP to confirm enrolment. 5. System generates 10 single-use backup codes, shown once, stored hashed. 6. Enrolment is recorded in user_mfa_methods with enrolled_at.

MFA verification flow at login: 1. Password verified → MFA challenge issued. 2. User submits OTP / passkey assertion. 3. On success, full session is established. 4. On 3 consecutive MFA failures within 5 minutes, lock the account.

5.5 Personal Access Tokens (PAT)

PATs let users and machine identities authenticate to the API without a session.

Attribute Value
Format tgc_<env>_<random_32> (e.g., tvb_live_a1b2c3...)
Storage Argon2id-hashed in personal_access_tokens table
Display Full token shown once at creation; only prefix shown thereafter
Scopes Subset of user's permissions; cannot exceed
Expiry Mandatory; max 365 days; default 90 days
IP allow-list Optional CIDR list enforced at request time
Rotation UI-driven; superseded tokens kept for 24h grace period
Revocation Immediate (cache-busted across all app nodes)
Audit Every PAT use logged with request_id, ip, route, partner_id

5.6 SSO (Phase 2)

For partners with enterprise IdPs: - OIDC (preferred) — travoBooks acts as relying party. - SAML 2.0 — for legacy IdPs. - JIT provisioning — first-time SAML/OIDC users get a viewer role; partner_admin must elevate. - SCIM 2.0 — automatic user lifecycle sync (Phase 3).

6. Inputs → processing → outputs

Login (password + MFA)

Input: {partner_slug, email, password, mfa_code?}

Processing: 1. Resolve partner_id from slug. 2. Look up user by (partner_id, email). 3. Bcrypt-compare password against password_hash. 4. Apply rate-limit (Redis sliding window keyed by (partner_id, email) and by source IP). 5. If MFA required, issue or verify challenge. 6. Create session record in Redis. 7. Set session cookie. 8. Emit auth.login.success audit event.

Output: Redirect to dashboard; cookie set.

API call with PAT

Input: HTTP request with Authorization: Bearer tvb_live_<token>

Processing: 1. Parse token, look up by prefix in personal_access_tokens. 2. Argon2id verify the suffix against stored hash. 3. Check expires_at, revoked_at. 4. Check IP allow-list if configured. 5. Load associated user + permission set. 6. Attach principal to request context. 7. Increment pat.usage_count; update last_used_at. 8. Emit auth.pat.used audit event.

Output: Request proceeds to controller with authenticated principal.

7. Module dependencies

Direction Module
Depends on User Management (Ch 2.1), Multi-Tenancy (Ch 1.1), Audit Logs (Ch 8.2)
Depended on by Every authenticated endpoint in the platform

8. Security & permissions

  • Authentication endpoints have stricter rate-limits than other routes.
  • Failed login attempts emit telemetry that feeds the WAF and abuse-detection system.
  • Account-takeover signals trigger automatic forced password reset and notification.
  • Tokens are never returned twice — if lost, they must be recreated.
  • The last_password_change_at timestamp is tracked; downstream PATs older than this timestamp can optionally be force-rotated by policy.

9. Validation rules

Code Condition
AUTH_INVALID_CREDENTIALS Email/password mismatch (generic — never reveal which)
AUTH_ACCOUNT_LOCKED Account locked due to failed attempts
AUTH_ACCOUNT_DISABLED users.is_active = FALSE
AUTH_MFA_REQUIRED Password OK but MFA challenge pending
AUTH_MFA_INVALID_CODE OTP / passkey assertion failed
AUTH_PASSWORD_EXPIRED Password age exceeded policy max
AUTH_PASSWORD_BREACHED New password matches known-breached set
AUTH_PAT_REVOKED Token has been revoked
AUTH_PAT_EXPIRED Token past expires_at
AUTH_PAT_IP_DENIED Caller IP not in PAT allow-list
AUTH_SESSION_EXPIRED Session past idle or absolute timeout
AUTH_PARTNER_SUSPENDED Partner account is suspended
AUTH_RATE_LIMITED Too many requests from this principal/IP

10. Error handling

The login API never distinguishes between "user does not exist" and "password incorrect" — both return AUTH_INVALID_CREDENTIALS. The MFA challenge response never reveals whether MFA is enrolled until the password phase succeeds. Lockout messages do not disclose lockout duration to the requester (they are logged for support, not shown to attacker).

For PAT failures, the response is 401 Unauthorized with no body discriminator — observability is internal.

11. Real-world examples

Example A — Accountant logs in from new device

  1. Accountant [email protected] (partner beta-travel) logs in.
  2. Password validates.
  3. Geo-IP shows session originating from Singapore; last 30 days of logins were from Bangladesh.
  4. Risk score elevated → MFA challenge issued plus email notification "New login from Singapore".
  5. Ria enters TOTP → session established.
  6. auth.login.success audit event recorded with risk_score=0.62, mfa_method=totp.

Example B — API key for booking automation

  1. Beta Corp dev creates a PAT tvb_live_a1b2... with scope bookings.read.partner, bookings.create.partner and IP allow-list 198.51.100.0/24.
  2. Dev integrates into their corporate booking bot.
  3. Bot calls POST /api/v1/bookings from 198.51.100.45 with the bearer token.
  4. Auth layer verifies token, IP, scope → request proceeds.
  5. Usage metrics are visible in the partner UI; rate-limit headers tell the bot when to back off.

Example C — Session hijack attempt detected

  1. Attacker steals session cookie via XSS in third-party widget (hypothetical — travoBooks' CSP prevents it).
  2. Attacker replays cookie from a different IP / User-Agent.
  3. Session-binding mismatch raises risk_score to 0.95.
  4. Session is force-terminated; original user notified by email.
  5. auth.session.suspicious_replay audit event recorded.

12. Step-by-step workflow

sequenceDiagram autonumber actor U as User participant N as Nginx (TLS) participant A as Auth Controller participant R as Redis participant DB as MySQL participant AL as Audit Log U->>N: POST /login {email, password} N->>A: forward A->>R: rate-limit check R-->>A: ok A->>DB: SELECT user WHERE (partner_id, email) DB-->>A: user row A->>A: argon2id_verify(password, hash) alt password fails A->>DB: UPDATE failed_attempts+1 A->>AL: auth.login.failure A-->>U: 401 AUTH_INVALID_CREDENTIALS else password ok, MFA required A->>R: store mfa_challenge_token A-->>U: 200 {state: mfa_required} U->>A: POST /login/mfa {challenge_token, code} A->>DB: SELECT mfa_secret A->>A: totp_verify(code, secret) alt mfa fails A->>AL: auth.mfa.failure A-->>U: 401 AUTH_MFA_INVALID_CODE else mfa ok A->>R: create session A->>AL: auth.login.success A-->>U: 302 → dashboard (Set-Cookie) end end

13. Database tables touched

Table Role
users Identity record, password_hash, mfa_required
user_mfa_methods Enrolled MFA factors per user
user_mfa_backup_codes Hashed single-use backup codes
user_login_attempts Failed-attempt counter + lockout state
personal_access_tokens Hashed PATs with scope, expiry, IP allow-list
sessions (Redis-backed; persistent log in session_history) Active sessions
audit_logs Authentication events
password_history Last 12 hashes

14. Future scalability

  • WebAuthn / Passkeys — Phase 2, becomes the preferred MFA factor; passwords retained as a recovery mechanism only.
  • Risk-based adaptive auth — Phase 2, ML-scored risk that adjusts MFA frequency.
  • Step-up auth API — Phase 2, exposes require_mfa(action) to controllers so individual high-risk actions (large refund, payout) can demand fresh MFA regardless of session state.
  • Hardware-token (FIDO2) support for enterprise partners — Phase 3.
  • SCIM 2.0 for SSO partner lifecycle — Phase 3.

15. Common pitfalls

  • ⚠️ Don't expose user-existence via differing error messages. Always return the same generic message on credential failure.
  • ⚠️ Don't make MFA bypass-able via "remember this device". travoBooks' policy is per-session — no persistent MFA-skip cookie for financial roles.
  • 🔒 PATs are bearer tokens — treat them like cash. UI must mask, transport must be TLS, storage must be hashed.
  • 🔒 Never log Authorization headers. Sanitisation must happen at the structured-logging layer before serialisation.
  • ⚠️ Don't tie session lifetime to "Remember Me" without re-checking permission cache. Permission changes must invalidate stale sessions via role_set_version (see Ch 2.1).