Local Auth - Device Authentication
Local device authentication using biometrics (Face ID, Touch ID, fingerprint) and device credentials (PIN, pattern, password). Configurable security levels from basic to banking-grade.
When to Use This Skill
- Adding biometric/device unlock to an app
- Implementing app lock after background timeout
- Securing sensitive actions (payments, delete, view PII)
- User asks "biometric", "face id", "fingerprint", "app lock", "local auth"
When NOT to Use This Skill
- Remote authentication - Use
/auth,/social-login,/phone-auth - Session tokens - Handled by
/authand/data - Secure storage - Already in
/core(flutter_secure_storage)
Questions to Ask
Before generating code, ask these questions:
- Use case: App unlock after timeout OR sensitive action confirmation OR both?
- Security level: Trust device (simple) OR detect biometric changes (banking-grade)?
- Lock screen: Generate lock screen UI OR service only?
- Settings toggle: Generate enable/disable toggle widget?
- App PIN: Include app-level PIN for devices without lock screen?
- Timeout: How long in background before requiring re-auth? (0 = immediate)
- Failure behavior: Force full re-login OR let device handle lockout?
Quick Reference
Dependencies
dependencies:
local_auth: ^2.3.0
Security Levels
| Level | Biometric Change | Use Case |
|---|---|---|
| Simple | Trust any enrolled biometric | Social apps, low-risk |
| Banking | Detect changes, require re-login | Finance, health, PII |
Authentication Options
| Option | iOS | Android |
|---|---|---|
| Face ID / Face Unlock | Yes | Yes |
| Touch ID / Fingerprint | Yes | Yes |
| Passcode | Yes | Yes |
| PIN / Pattern | N/A | Yes |
Core Components
| Component | Purpose |
|---|---|
LocalAuthService |
Wraps local_auth, handles platform checks |
LocalAuthNotifier |
State management, timeout tracking |
LocalAuthSettings |
User preferences (enabled, timeout) |
LockScreen |
Optional full-screen auth prompt |
LocalAuthToggle |
Optional settings widget |
AppPinService |
Optional app-level PIN (no device lock) |
Workflow
Phase 1: Gather Requirements
Ask all questions from "Questions to Ask" section before proceeding.
Phase 2: Platform Setup
- iOS: Add
NSFaceIDUsageDescriptionto Info.plist - Android: Add
USE_BIOMETRICpermission to AndroidManifest.xml - Run
flutter pub get
Phase 3: Create Core Files
- Create
LocalAuthServiceinlib/core/services/ - Create
LocalAuthNotifier+ state inlib/core/providers/ - Create
LocalAuthSettingsfor preferences
Phase 4: Optional Components
Based on user answers:
- Lock screen: Create
LockScreenwidget - Settings toggle: Create
LocalAuthTogglewidget - App PIN: Create
AppPinServiceand PIN entry UI - Banking security: Add biometric state tracking
Phase 5: Integration
- Add
WidgetsBindingObserverfor app lifecycle - Configure timeout-based re-auth
- Wrap sensitive actions with auth check
Phase 6: Verify
dart run .claude/skills/local-auth/scripts/check.dart
Core API
// Check availability
final canAuth = await localAuthService.canAuthenticate();
// Authenticate (biometricOnly: false allows PIN/pattern fallback)
final result = await localAuthService.authenticate(reason: 'Unlock');
See: reference/services/local_auth_service.dart for full API.
File Structure
lib/core/
├── services/local_auth_service.dart # Core service
├── providers/local_auth_provider.dart # Notifier + settings
└── widgets/lock_screen.dart # Optional UI
See: checklist.md for full file list with optional components.
Failure Types
| Type | When | UI Action |
|---|---|---|
LocalAuthNotAvailable |
No biometric/lock enrolled | Show setup prompt |
LocalAuthNotEnrolled |
Biometric not set up | Show settings link |
LocalAuthFailed |
User failed auth | Retry or fallback |
LocalAuthCancelled |
User cancelled | Silent (not error) |
BiometricsChanged |
Fingerprint/face changed | Force full re-login |
LocalAuthLockout |
Too many failures | Show countdown/message |
Guides
| File | Content |
|---|---|
| setup-guide.md | Platform setup (iOS/Android) |
| security-guide.md | Security levels, biometric change detection |
| patterns-guide.md | Usage patterns, timeout, lifecycle |
| troubleshooting-guide.md | Common issues and solutions |
| checklist.md | Verification checklist |
Reference Files
See: reference/ directory for complete implementations (services, providers, widgets, utils).
Checklist
Platform Setup:
-
local_auth: ^2.3.0added to pubspec.yaml - iOS:
NSFaceIDUsageDescriptionin Info.plist - Android:
USE_BIOMETRICpermission in AndroidManifest.xml -
flutter pub getrun successfully
Core Implementation:
-
LocalAuthServicecreated with availability checks -
LocalAuthNotifiermanages auth state -
LocalAuthSettingsstores user preferences - App lifecycle observer tracks background time
Optional Components:
- Lock screen UI (if requested)
- Settings toggle widget (if requested)
- App PIN service (if requested)
- Biometric change detection (if banking-grade)
Testing:
- Biometric auth works on real device
- Device credential fallback works
- Timeout triggers re-auth correctly
- Cancellation handled silently
Related Skills
/auth- Base authentication (this extends it for local unlock)/social-login,/phone-auth- Remote auth methods/design- Lock screen UI patterns/i18n- Localized auth prompts/testing- Test local auth flows
Next Steps
After running this skill:
- Test on real device (simulators have limitations)
- Run
/i18nfor auth prompt strings - Run
/designfor lock screen polish - Run
/testingfor auth flow tests