skills/mobile-biometric-auth-expert/SKILL.md
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).
npx skillsauth add curiositech/windags-skills mobile-biometric-auth-expertInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert in implementing biometric authentication with Face ID, Touch ID, Android BiometricPrompt, secure credential storage, and Passkeys/WebAuthn.
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
Rubber Stamp Biometric - Using biometric UI without secure storage
Enrollment Invalidation Blind Spot - Ignoring biometric enrollment changes
Fallback Chain Break - No recovery path when biometrics fail
Prompt Fatigue - Biometric prompts for low-value actions
Custom UI Trust Gap - Building custom biometric interfaces
Passkey Implementation with Biometric Fallback:
// 1. Check WebAuthn support
guard ASAuthorizationPlatformPublicKeyCredentialProvider.isSupported else {
// Fall back to biometric-gated token storage
return authenticateWithStoredToken()
}
// 2. Create passkey request
let challenge = Data("server-challenge".utf8)
let request = ASAuthorizationPlatformPublicKeyCredentialProvider
.createCredentialRegistrationRequest(
challenge: challenge,
name: "[email protected]",
userID: Data("user-123".utf8)
)
// 3. Handle success/failure
func authorizationController(controller: ASAuthorizationController,
didCompleteWithAuthorization authorization: ASAuthorization) {
if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialRegistration {
// Passkey created - store credential ID, send public key to server
storeCredentialID(credential.credentialID)
sendPublicKeyToServer(credential.rawAttestationObject)
}
}
// 4. Graceful degradation
func authorizationController(controller: ASAuthorizationController,
didCompleteWithError error: Error) {
if case ASAuthorizationError.canceled = error {
// User canceled - offer biometric-gated password login
showBiometricPasswordFallback()
}
}
Trade-offs navigated:
Use other skills for:
oauth-oidc-implementerapi-security-expertsecret-management-expertmobile-payment-integration-specialistsecurity-auditordatabase-security-expertThis skill handles: Device-level biometric authentication, secure credential storage, WebAuthn/Passkey implementation, and biometric UX flows only.
tools
Building resilient distributed systems with circuit breakers, retries with full-jitter exponential backoff, retry budgets (per-request 3-attempt + per-client 10% ratio per Google SRE), deadline propagation, and the cascading-failure math (4 layers × 3 retries = 64x amplification). Grounded in Resilience4j, Microsoft Cloud Patterns, AWS Architecture Blog (Marc Brooker), and Google SRE Book.
testing
Designing HTTP cache headers that work correctly across browsers, CDNs, and shared proxies — `Cache-Control` directives per RFC 9111, `stale-while-revalidate` and `stale-if-error` per RFC 5861, the Vary header for varying responses, and surrogate keys for tag-based purging. Grounded in IETF RFCs and Cloudflare/Fastly docs.
development
Use when designing or fixing a Content Security Policy on a real site, choosing between nonce-based and hash-based CSP, adding strict-dynamic, debugging "Refused to execute inline script" errors, deploying CSP in report-only mode first, configuring report-to / report-uri, or auditing an existing policy for unsafe-inline / unsafe-eval / wildcards. Triggers: "CSP blocks legitimate inline script", strict-dynamic, nonce-{RANDOM}, sha256-{HASH}, object-src none, base-uri none, frame-ancestors, Trusted Types, X-Content-Security-Policy obsolete, report-only vs enforced. NOT for general HTTP security headers (HSTS, COOP/COEP), Trusted Types deep dive, CORS configuration, or building a WAF.
tools
Choosing and operating an HTTP API versioning strategy that doesn't break clients — Stripe's date-based pinned versions, the Deprecation/Sunset header pair (RFC 9745 + RFC 8594), URI vs header vs media-type approaches, and the version-transformer pattern. Grounded in Stripe's published architecture and IETF RFCs.