Banking apps live at the intersection of high-stakes correctness and user experience. The interview tests whether you can design auth that is both secure and not user-hostile, transactions that cannot be lost or duplicated, and an experience that survives the sketchiest network conditions without compromising trust.
Functional requirements
- Login with biometrics or PIN
- View account balances and transactions
- Transfer money between accounts and to other people
- Pay bills
- Deposit checks via mobile camera
- Push notifications for transactions
Non-functional
- Zero tolerance for lost or duplicated transfers
- Sub-second response for balance queries
- Strong auth: regulatory, biometric, MFA
- PCI compliance and data-at-rest encryption
Auth flow
First-time setup:
- User logs in with username + password (server-side bcrypt or Argon2)
- Server returns a refresh token (long-lived, stored in iOS Keychain / Android Keystore)
- Client requests biometric enrollment — uses Touch ID / Face ID / Android Biometric to wrap the refresh token with a key tied to the secure enclave
Subsequent logins:
- User taps fingerprint/face → device unlocks the wrapped token → exchange for short-lived access token
- Access token (~15 min) signs API requests
- Sensitive operations (transfer over $X, change password) require step-up auth (PIN or fresh biometric)
Transaction flow
Critical path. Design for at-least-once delivery with idempotency:
- User taps “Send $100 to John”
- Client generates idempotency key (UUID)
- POST to
/transferswith idempotency key in header - Wait up to 10 seconds for response
- If timeout, retry with same key — server dedupes and returns existing transaction
- Show explicit “submitting” state, never optimistically confirm
- Confirmed only when server returns final transaction ID
Mobile check deposit
Camera-based:
- Capture front and back of check at high resolution (4K)
- Run on-device edge detection to crop to the check
- Show preview, let user retake if blurry
- Upload to server (encrypted in transit + at rest)
- Server runs OCR + fraud detection asynchronously
- Funds available 1–3 business days later
Push notifications
Push payloads do not contain sensitive data. Format: “Transaction posted to your account.” User opens app to see details.
Privacy mode: even less in the lock screen — “Update from [Bank Name].”
Offline behavior
Strict — banking is not offline-friendly. Disable transfers and bill pay when offline. Show last-known balance with a “as of [time]” disclaimer.
Security hardening
- Detect rooted/jailbroken devices and refuse to run
- Disable screenshots and screen recording on transfer screens
- Cert pinning to prevent MITM
- Force re-auth after 5 minutes of inactivity
- Out-of-band fraud monitoring on the backend
Frequently Asked Questions
How do you prevent a malicious app on the same device from reading your data?
iOS sandbox isolates app data; same on Android. Sensitive credentials in Keychain/Keystore, not on disk. Biometric-tied keys mean even root access on a jailbroken device cannot trivially extract them.
What if the user changes their fingerprint or face mid-session?
Biometric enrollment changes invalidate the key. User has to re-enroll with their password.
How do you handle ATO (account takeover) at the mobile layer?
Defense in depth: device fingerprinting, login geolocation anomalies, behavioral biometrics, MFA on suspicious logins, and out-of-band confirmation for high-value transfers.