Skip to content

Commit 05bdf16

Browse files
committed
feat(rotation): add key rotation functionality with automatic re-encryption and event handling
1 parent defb2f7 commit 05bdf16

7 files changed

Lines changed: 795 additions & 75 deletions

File tree

README.md

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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.
333334
Use `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

Comments
 (0)