πŸ›‘οΈ MemGuard

Android iOS Windows macOS Linux

Hybrid secure storage for Flutter with zero-leak memory protection and hardware-backed encryption.

MemGuard combines ultra-fast Rust FFI memory storage with hardware-backed platform security (Android KeyStore, iOS Keychain) to give you the best of both worlds: blazing performance for ephemeral data and military-grade protection for persistent secrets.


✨ Features

πŸš€ Dual Storage Modes

Memory Storage (Rust FFI)

  • ⚑ Zero-copy direct access β€” no Dart VM overhead
  • πŸ”₯ Ephemeral by design β€” data vanishes on app close
  • 🧠 Protected memory β€” explicit zeroing prevents leaks
  • πŸ” Optional encryption β€” AES-256-GCM in Rust
  • 🎯 Perfect for: Session tokens, API keys, temporary credentials

Device Secure Storage (Platform Channels)

  • πŸ”’ Hardware-backed encryption β€” Android KeyStore (StrongBox/TEE)
  • πŸ’Ύ Persistent across restarts β€” survives app kills
  • πŸ›‘οΈ Zero platform channel leaks β€” only boolean flags transmitted
  • πŸ—„οΈ Disk-backed with Rust cache β€” fast reads after first access
  • 🎯 Perfect for: User credentials, refresh tokens, sensitive settings

πŸ” Zero-Leak Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    YOUR DART CODE                           β”‚
β”‚         β€’ Never touches sensitive data directly            β”‚
β”‚         β€’ Only receives boolean status flags               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
                   β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   MemGuard Plugin   β”‚  ← You are here
         β”‚   (Dart API Layer)  β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β–Ό                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Rust FFI       β”‚  β”‚  Platform Channel  β”‚
β”‚  (Memory Cache)  β”‚  β”‚  (Kotlin/Swift)    β”‚
β”‚                  β”‚  β”‚                    β”‚
β”‚ β€’ Direct access  β”‚  β”‚ β€’ KeyStore/Keychainβ”‚
β”‚ β€’ Zero-copy      β”‚  β”‚ β€’ Encrypted files  β”‚
β”‚ β€’ Protected mem  β”‚  β”‚ β€’ No plaintext     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Critical Design Decision:

  • Memory mode: Data lives ONLY in Rust β€” Dart never sees plaintext
  • Secure mode: Platform channels return true/false/null β€” Dart fetches from Rust cache
  • Result: Zero attack surface in Dart VM and platform channels

πŸš€ Quick Start

Installation

dependencies:
  memguard: ^2.1.4

Basic Usage

import 'package:memguard/memguard.dart';

void main() {
  runApp(
    MemGuard(
      // Choose your storage mode
      storageType: StorageType.memory, // or StorageType.deviceSecure

      // Memory options (for memory mode)
      enableEncryptionMemory: true,
      autoCleanupMemory: true,
      cleanupIntervalMemory: Duration(minutes: 10),

      // Debug logging
      showLog: true,

      child: MyApp(),
    ),
  );
}

// Then use anywhere in your app:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  Future<void> saveToken() async {
    // Store securely
    await MemGuardStatic.store('auth_token', 'super_secret_jwt');

    // Retrieve
    final token = await MemGuardStatic.retrieve('auth_token');
    print('Token: $token');

    // Check existence
    final exists = await MemGuardStatic.contains('auth_token');

    // Delete
    await MemGuardStatic.delete('auth_token');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('MemGuard Demo')),
      body: Center(
        child: ElevatedButton(
          onPressed: saveToken,
          child: Text('Test Secure Storage'),
        ),
      ),
    );
  }
}

πŸ“– API Reference

Storage Operations

// Store data
await MemGuardStatic.store('key', 'value');

// Retrieve data
String? value = await MemGuardStatic.retrieve('key');

// Check if key exists
bool exists = await MemGuardStatic.contains('key');

// Delete key
await MemGuardStatic.delete('key');

// Get storage statistics
Map<String, dynamic> stats = await MemGuardStatic.getStats();

// Cleanup memory (memory mode only)
MemGuardStatic.cleanupMemory();

// Cleanup all storage
MemGuardStatic.cleanupAll();

Advanced: Zero-Copy Operations (Memory Mode Only)

For maximum performance, access data directly in Rust memory without copying to Dart:

// Perform cryptographic operations without copying to Dart
final signature = await MemGuardStatic.performSecureOperation<String>(
  'private_key',
  (dataPtr, length) {
    // Direct pointer access β€” zero copies!
    final bytes = dataPtr.asTypedList(length);

    // Perform operation (e.g., sign with private key)
    final signature = yourCryptoLib.sign(bytes, message);

    return signature;
    // Buffer automatically zeroed after this scope
  },
);

Use cases:

  • Cryptographic signing without key exposure
  • Hash computation on sensitive data
  • Encryption/decryption with in-memory keys
  • Any operation where data must never touch Dart heap

🎯 Storage Mode Comparison

Feature Memory Storage Device Secure Storage
Speed ⚑ Instant (Rust FFI) πŸ‡ Fast (disk + cache)
Persistence ❌ Ephemeral βœ… Survives restarts
Encryption Optional (Rust AES) βœ… Hardware-backed
Auto-cleanup βœ… Configurable ❌ Manual only
Zero-copy βœ… Yes ❌ No
Best for Session data Long-term secrets

When to Use Memory Storage

MemGuard(
  storageType: StorageType.memory,
  enableEncryptionMemory: true,
  autoCleanupMemory: true,
  cleanupIntervalMemory: Duration(minutes: 5),
  child: MyApp(),
)

βœ… Perfect for:

  • Session tokens (expire on app close)
  • Temporary API keys
  • In-flight credentials
  • Crypto operations (use performSecureOperation)
  • Any data that shouldn't persist

When to Use Device Secure Storage

MemGuard(
  storageType: StorageType.deviceSecure,
  child: MyApp(),
)

βœ… Perfect for:

  • User login credentials
  • OAuth refresh tokens
  • Biometric authentication keys
  • App settings with sensitive data
  • Anything that must survive app restart

πŸ”§ Configuration Options

Memory Storage Configuration

MemGuard(
  storageType: StorageType.memory,

  // Enable AES-256-GCM encryption in Rust
  enableEncryptionMemory: true,

  // Auto-cleanup on app background/close
  autoCleanupMemory: true,

  // How often to run cleanup (if auto enabled)
  cleanupIntervalMemory: Duration(minutes: 10),

  // Enable debug logging
  showLog: true,

  child: MyApp(),
)

Device Secure Storage Configuration

MemGuard(
  storageType: StorageType.deviceSecure,

  // Enable Rust cache for faster reads (recommended)
  enableEncryptionMemory: true,

  // Enable debug logging
  showLog: true,

  child: MyApp(),
)

πŸ›‘οΈ Security Features

What MemGuard Protects Against

βœ… Memory Dumps β€” Sensitive data never stored in Dart VM heap
βœ… Platform Channel Interception β€” Only boolean flags transmitted
βœ… Heap Inspection β€” Rust memory is protected and zeroed
βœ… Data Tampering β€” GCM authentication tags verify integrity
βœ… Key Extraction β€” Hardware-backed keys never leave secure enclave
βœ… Root Access (partial) β€” Keys resist extraction even on rooted devices

Attack Resistance

// ❌ BAD: Traditional secure storage
await secureStorage.write('token', 'secret'); // Plaintext in Dart heap!

// βœ… GOOD: MemGuard memory storage
await MemGuardStatic.store('token', 'secret'); // Only in Rust protected memory

// βœ… BETTER: MemGuard device secure
MemGuard(storageType: StorageType.deviceSecure, ...); // Hardware encryption + Rust cache

What MemGuard Does NOT Protect Against

❌ Physical device seizure by sophisticated attackers
❌ Compromised OS/kernel (malware with root/system privileges)
❌ User-authorized access (screen recording, accessibility services)
❌ State-level adversaries with hardware forensics tools

Threat Model: MemGuard is designed for production app security against common attack vectors (malware, memory dumps, network interception). It is NOT a substitute for end-to-end encryption or protection against nation-state actors.


πŸ“Š Storage Statistics

final stats = await MemGuardStatic.getStats();
print(stats);

// Memory Storage Output:
// {
//   "items_count": 5,
//   "total_size_bytes": 2048,
//   "encrypted_items": 5,
//   "platform": "android",
//   "rust_version": "1.70.0",
//   "storage_type": "memory"
// }

// Device Secure Storage Output:
// {
//   "storage_type": "hardware_backed_keystore",
//   "encryption_type": "aes_256_gcm",
//   "key_strength": "256_bit",
//   "rust_initialized": true,
//   "items_count": 3,
//   "total_size_bytes": 4096,
//   "directory_path": "/data/user/0/com.app/files/memguard_secure",
//   "timestamp": 1701234567890
// }

🎨 Convenience Extensions

String Extension

// Store string directly
await "my_secret_value".storeAs('api_key');

// Works with any storage type
await "refresh_token_xyz".storeAs('refresh_token');

Context Extension

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Access MemGuard core directly
    final core = context.memguard;

    // Check initialization status
    print('Storage type: ${core.currentStorageType}');
    print('Rust ready: ${core.isRustInitialized}');

    return Container();
  }
}

πŸ”„ Lifecycle Management

MemGuard automatically handles app lifecycle events:

// Memory Storage: Auto-cleanup on background
MemGuard(
  storageType: StorageType.memory,
  autoCleanupMemory: true, // ← Cleans on app pause/background
  child: MyApp(),
)

// Lifecycle events handled:
// β€’ AppLifecycleState.paused β†’ cleanupMemory()
// β€’ AppLifecycleState.inactive β†’ cleanupMemory()
// β€’ AppLifecycleState.detached β†’ cleanupAll()

Manual cleanup:

// Clean memory only (memory mode)
MemGuardStatic.cleanupMemory();

// Clean everything (all modes)
MemGuardStatic.cleanupAll();

πŸ› Error Handling

try {
  await MemGuardStatic.store('key', 'value');
} catch (e) {
  if (e is StateError) {
    // MemGuard not initialized
    print('Initialize MemGuard first!');
  } else if (e is UnsupportedError) {
    // Feature not available (e.g., zero-copy on device secure)
    print('Operation not supported for this storage type');
  } else if (e is ArgumentError) {
    // Storage type mismatch
    print('Wrong storage type specified');
  } else {
    // Other errors (platform exceptions, etc.)
    print('Storage error: $e');
  }
}

Common errors:

  • StateError: MemGuard is not initialized β€” Wrap your app in MemGuard widget
  • UnsupportedError: Secure buffer operations only available for memory storage β€” Use StorageType.memory for zero-copy
  • ArgumentError: Requested storage type does not match β€” Don't mix storage types in same session

πŸ“± Platform Support

Platform Memory Storage Device Secure Status
Android βœ… Full βœ… Full Tested βœ…
iOS ⚠️ Untested ⚠️ Untested Needs Testing
Windows ⚠️ Untested ⚠️ Untested Needs Testing
macOS ⚠️ Untested ⚠️ Untested Needs Testing
Linux βœ… Full ❌ Not Available Tested βœ…

Android Requirements

  • Minimum: API 23 (Android 6.0 Marshmallow)
  • Recommended: API 28+ (Android 9.0 Pie) for StrongBox support

🐧 Linux Compatibility

βœ… Supported

  • Ubuntu 20.04+ βœ… (22.04 tested)
  • Debian 11+ βœ…
  • Fedora 34+ βœ…
  • Arch Linux βœ…
  • Manjaro βœ…
  • Pop!_OS 20.04+ βœ…
  • Linux Mint 20+ βœ…
  • Elementary OS 6+ βœ…

Requires glibc 2.31+ and 64-bit (x86_64).


πŸ—οΈ Architecture

MemGuard is built on top of MemGuard Core β€” the native Rust + Kotlin foundation that powers the zero-leak security model.

Stack:

  • Dart Layer (this plugin): High-level Flutter API
  • Rust FFI: Protected memory allocation and cryptography
  • Kotlin Platform: Android KeyStore integration and encrypted file I/O
  • Native Libraries: Compiled .so binaries for ARM/x86

See the MemGuard Core README for low-level implementation details.


πŸ§ͺ Testing

// Example test
void main() {
  test('Memory storage lifecycle', () async {
    MemGuardStatic.initMemoryStorage(
      enableEncryptionMemory: true,
      autoCleanupMemory: false,
      cleanupIntervalMemory: Duration(minutes: 10),
    );

    await MemGuardStatic.store('test_key', 'test_value');

    final value = await MemGuardStatic.retrieve('test_key');
    expect(value, 'test_value');

    await MemGuardStatic.delete('test_key');

    final deleted = await MemGuardStatic.retrieve('test_key');
    expect(deleted, isNull);
  });
}

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Areas for Contribution

  • iOS/macOS platform implementation
  • Windows/Linux platform implementation
  • Additional encryption algorithms
  • Performance benchmarks
  • Integration tests
  • Documentation improvements

πŸ™ Acknowledgments

Built with:

  • Rust FFI for memory-safe protected storage
  • Android KeyStore for hardware-backed encryption
  • flutter_fastlog for high-performance logging
  • MemGuard Core for the native foundation

⚠️ Security Notice

MemGuard implements defense-in-depth secure storage with zero-leak architecture. However, no client-side storage is absolutely secure. Always:

  • βœ… Validate critical operations server-side
  • βœ… Use certificate pinning for network requests
  • βœ… Implement request signing for API calls
  • βœ… Rotate sensitive credentials regularly
  • βœ… Enable biometric authentication when available

For high-security applications, combine MemGuard with additional layers of protection (HSM, remote attestation, etc.).



πŸ’¬ Support

Libraries

memguard
πŸ›‘οΈ MemGuard - Hybrid Storage Protection