@@ -31,6 +31,7 @@ Modern secure storage for React Native, powered by Nitro Modules. Version 6 ship
3131- [ ⚡️ Quick start] ( #-quick-start )
3232- [ 📚 API reference] ( #-api-reference )
3333- [ 🔐 Access control & metadata] ( #-access-control--metadata )
34+ - [ 🔑 Key rotation] ( #-key-rotation )
3435- [ ❗ Error handling] ( #-error-handling )
3536- [ 🧪 Simulators and emulators] ( #-simulators-and-emulators )
3637- [ 📈 Performance benchmarks] ( #-performance-benchmarks )
@@ -333,7 +334,164 @@ See `src/sensitive-info.nitro.ts` for full TypeScript definitions.
333334Use ` getSupportedSecurityLevels() ` to tailor UX before prompting users. For example, disable Secure Enclave options on simulators.
334335
335336> [ !TIP]
336- > Need to demo biometrics on a simulator? Use Xcode’s “Features → Face ID” and Android Studio’s “Fingerprints” toggles to simulate successful scans.
337+ > Need to demo biometrics on a simulator? Use Xcode's "Features → Face ID" and Android Studio's "Fingerprints" toggles to simulate successful scans.
338+
339+ ## 🔑 Key rotation
340+
341+ Automatically rotate encryption keys to maintain security over time, with zero-downtime re-encryption of stored secrets. This feature implements envelope encryption with key versioning, ensuring forward secrecy and compliance with security best practices.
342+
343+ ### 🛡️ Security benefits
344+
345+ - ** Forward secrecy** : Old keys become useless even if compromised, protecting historical data
346+ - ** Compliance** : Meets security standards requiring regular key rotation (NIST, PCI DSS, etc.)
347+ - ** Post-compromise security** : Limits damage from key exposure by automatically cycling keys
348+ - ** Hardware-backed** : Uses Secure Enclave (iOS) and Keystore/StrongBox (Android) for key protection
349+
350+ ### ⚡ Advantages
351+
352+ - ** Zero downtime** : Re-encryption happens automatically in the background
353+ - ** Event-driven** : Real-time notifications for rotation lifecycle events
354+ - ** Configurable** : Customize rotation intervals, triggers, and behavior
355+ - ** Cross-platform** : Consistent API across iOS and Android
356+ - ** Performance optimized** : Batched operations with progress tracking
357+
358+ ### 🚀 Quick setup
359+
360+ ``` tsx
361+ import {
362+ initializeKeyRotation ,
363+ rotateKeys ,
364+ getRotationStatus ,
365+ onRotationEvent
366+ } from ' react-native-sensitive-info'
367+
368+ // Initialize automatic rotation (30 days, biometric triggers)
369+ await initializeKeyRotation ({
370+ enabled: true ,
371+ rotationIntervalMs: 30 * 24 * 60 * 60 * 1000 , // 30 days
372+ rotateOnBiometricChange: true ,
373+ backgroundReEncryption: true
374+ })
375+
376+ // Listen for rotation events
377+ const unsubscribe = onRotationEvent ((event ) => {
378+ console .log (` ${event .type }: ${event .reason } ` )
379+ if (event .type === ' rotation:completed' ) {
380+ console .log (` Re-encrypted ${event .itemsReEncrypted } items ` )
381+ }
382+ })
383+
384+ // Manual rotation
385+ const result = await rotateKeys ({
386+ reason: ' User requested rotation'
387+ })
388+ console .log (` Rotated to key: ${result .newKeyVersion .id } ` )
389+
390+ // Check status
391+ const status = await getRotationStatus ()
392+ console .log (` Current key: ${status .currentKeyVersion ?.id } ` )
393+ ```
394+
395+ ### 📋 API reference
396+
397+ | Method | Description |
398+ | --- | --- |
399+ | ` initializeKeyRotation(options) ` | Configure automatic key rotation settings |
400+ | ` rotateKeys(options) ` | Manually trigger key rotation |
401+ | ` getRotationStatus() ` | Get current rotation state and key information |
402+ | ` onRotationEvent(callback) ` | Subscribe to rotation lifecycle events |
403+ | ` reEncryptAllItems(options) ` | Re-encrypt all items with current key |
404+
405+ ### ⚙️ Configuration options
406+
407+ ``` tsx
408+ interface InitializeKeyRotationRequest {
409+ enabled? : boolean // Enable/disable automatic rotation
410+ rotationIntervalMs? : number // Time between rotations (default: 30 days)
411+ rotateOnBiometricChange? : boolean // Trigger on biometric enrollment changes
412+ rotateOnCredentialChange? : boolean // Trigger on device credential changes
413+ manualRotationEnabled? : boolean // Allow manual rotation triggers
414+ maxKeyVersions? : number // Maximum key versions to keep
415+ backgroundReEncryption? : boolean // Re-encrypt during rotation
416+ }
417+ ```
418+
419+ ### 🎯 Event types
420+
421+ Subscribe to rotation events for real-time feedback:
422+
423+ ``` tsx
424+ onRotationEvent ((event ) => {
425+ switch (event .type ) {
426+ case ' rotation:started' :
427+ console .log (` 🔄 Rotation started: ${event .reason } ` )
428+ break
429+ case ' rotation:completed' :
430+ console .log (` ✅ Completed: ${event .itemsReEncrypted } items in ${event .duration }ms ` )
431+ break
432+ case ' rotation:failed' :
433+ console .log (` ❌ Failed: ${event .reason } ` )
434+ break
435+ }
436+ })
437+ ```
438+
439+ ### 🔧 Advanced usage
440+
441+ > [ !TIP]
442+ > Use the example app's Key Rotation panel to explore all features interactively.
443+
444+ #### Custom rotation intervals
445+
446+ ``` tsx
447+ // Rotate every 7 days
448+ await initializeKeyRotation ({
449+ rotationIntervalMs: 7 * 24 * 60 * 60 * 1000 ,
450+ enabled: true
451+ })
452+ ```
453+
454+ #### Biometric change detection
455+
456+ ``` tsx
457+ // Auto-rotate when fingerprints/face change
458+ await initializeKeyRotation ({
459+ rotateOnBiometricChange: true ,
460+ rotateOnCredentialChange: true
461+ })
462+ ```
463+
464+ #### Manual bulk re-encryption
465+
466+ ``` tsx
467+ // Re-encrypt all items without rotating keys
468+ const result = await reEncryptAllItems ({
469+ service: ' myapp' ,
470+ batchSize: 50
471+ })
472+ console .log (` Re-encrypted ${result .itemsReEncrypted } items ` )
473+ ```
474+
475+ ### ⚠️ Important considerations
476+
477+ > [ !WARNING]
478+ > Key rotation is irreversible. Ensure you have backups before enabling automatic rotation in production.
479+
480+ > [ !IMPORTANT]
481+ > Background re-encryption may consume battery and data. Monitor performance on resource-constrained devices.
482+
483+ > [ !NOTE]
484+ > Rotation events are delivered asynchronously. UI updates should be handled in event callbacks.
485+
486+ ### 🔍 Troubleshooting
487+
488+ - ** Rotation not triggering** : Check that ` enabled: true ` and verify device time settings
489+ - ** Re-encryption failures** : Some items may fail if keys are invalidated; check error details
490+ - ** Performance issues** : Reduce ` rotationIntervalMs ` or disable ` backgroundReEncryption ` on low-end devices
491+ - ** Event not firing** : Ensure the event listener is set up before rotation starts
492+
493+ > [ !TIP]
494+ > The example app includes comprehensive logging and error handling for all rotation operations.
337495
338496## 🧪 Simulators and emulators
339497
0 commit comments