| license | Apache-2.0 |
| name | mobile-biometric-auth-expert |
| description | Mobile biometric authentication expert for Face ID, Touch ID, BiometricPrompt, Keychain/Keystore, and WebAuthn. Activate on: biometric authentication, Face ID, Touch ID, BiometricPrompt, Keychain, Keystore, WebAuthn, passkeys, FIDO2, device authentication. NOT for: OAuth/OIDC flows (use oauth-oidc-implementer), secret management (use secret-management-expert), general security (use security-auditor). |
| allowed-tools | Read,Write,Edit,Bash(docker:*,kubectl:*,terraform:*,npm:*,npx:*) |
| category | Mobile Development |
| tags | ["biometric","authentication","security","mobile"] |
| pairs-with | [{"skill":"oauth-oidc-implementer","reason":"Biometric auth often gates access to OAuth tokens stored in secure storage"},{"skill":"mobile-payment-integration-specialist","reason":"Payments require biometric confirmation for high-value transactions"}] |
Mobile Biometric Auth Expert
Expert in implementing biometric authentication with Face ID, Touch ID, Android BiometricPrompt, secure credential storage, and Passkeys/WebAuthn.
Decision Points
Biometric Availability Check:
If biometric hardware available AND enrolled:
→ Offer biometric as primary auth
If biometric hardware available BUT not enrolled:
→ Show enrollment prompt + fallback to password
If biometric hardware unavailable:
→ Use password/PIN only, hide biometric UI
Special cases:
- If user declined biometric permission: Store preference, don't re-prompt
- If biometric lockout (too many failures): Force device PIN, then re-enable
Authentication Flow Selection:
If first login on device:
→ Password auth → store token in secure storage → enable biometric gate
If returning user with stored credential:
→ Biometric prompt → decrypt stored token → validate/refresh if needed
If biometric prompt times out (>30s):
→ Show "Use Password" option → device PIN fallback
If biometric enrollment changed:
→ Invalidate stored credentials → require re-authentication
Storage Strategy:
If iOS:
→ Keychain with kSecAccessControlBiometryCurrentSet
If Android API 23+:
→ Keystore with setUserAuthenticationRequired(true)
If cross-platform framework:
→ Expo SecureStore or RN Keychain with biometric access control
Passkey vs Biometric-Gated Token:
If WebAuthn/Passkey supported AND user has existing account:
→ Offer passkey upgrade (future-proof, no token storage)
If new user registration:
→ Default to passkey flow, fallback to biometric-gated tokens
If enterprise/MDM environment:
→ Check policy for passkey allowlist before offering
Failure Modes
Rubber Stamp Biometric - Using biometric UI without secure storage
- Detection: Biometric success doesn't gate any Keychain/Keystore operations
- Diagnosis: Auth token stored in plain SharedPreferences/UserDefaults
- Fix: Move token to Keychain (iOS) or Keystore (Android) with biometric access control
Enrollment Invalidation Blind Spot - Ignoring biometric enrollment changes
- Detection: Old stored credentials work after user adds new fingerprint/face
- Diagnosis: Using kSecAccessControlBiometryAny instead of kSecAccessControlBiometryCurrentSet
- Fix: Configure invalidation on enrollment change, handle re-authentication gracefully
Fallback Chain Break - No recovery path when biometrics fail