Fasq Security
Fasq Security is an enterprise-grade extension for the FASQ core that provides robust encryption, secure storage, and encrypted persistence for your application’s state.
It is designed to protect sensitive user data, tokens, and PII (Personally Identifiable Information) both in memory and on disk.
Features
Section titled “Features”- 🔒 Advanced Encryption: Industry-standard AES-GCM encryption with 256-bit keys.
- 🛡️ Secure Key Storage: Platform-specific secure storage for encryption keys (Keychain for iOS/macOS, Keystore for Android).
- 💾 Encrypted Persistence: SQL-based persistence using Drift with at-rest encryption.
- ⚡ Isolate Processing: Offloads heavy encryption/decryption tasks to background isolates to keep the UI thread smooth.
- 🧹 Automatic Sanitization: Configurable hooks to wipe sensitive data from memory when the app enters the background.
Installation
Section titled “Installation”Add the security package to your project:
flutter pub add fasq_security[!TIP] This package integrates seamlessly with the Fasq core and all its adapters.
To use security features, you must initialize your QueryClient with a SecurityPlugin. The DefaultSecurityPlugin provides a battery-included implementation.
1. Basic Initialization
Section titled “1. Basic Initialization”Initialize the plugin during app startup to ensure encryption keys are ready before any queries are made.
import 'package:fasq/fasq.dart';import 'package:fasq_security/fasq_security.dart';
void main() async { WidgetsFlutterBinding.ensureInitialized();
// 1. Create the security plugin final securityPlugin = DefaultSecurityPlugin();
// 2. Initialize it (retrieves/generates keys) await securityPlugin.initialize();
// 3. Provide it to the QueryClient final client = QueryClient( securityPlugin: securityPlugin, );
runApp(QueryClientProvider( client: client, child: MyApp(), ));}2. Riverpod Integration
Section titled “2. Riverpod Integration”If you are using the Riverpod adapter, you can override the default security plugin provider:
ProviderScope( overrides: [ fasqSecurityPluginProvider.overrideWithValue( DefaultSecurityPlugin(), ), ], child: MyApp(),)Using Secure Queries
Section titled “Using Secure Queries”Once the security plugin is configured, you can mark any query as secure using the isSecure option.
QueryBuilder<SecretData>( queryKey: 'user-secrets'.toQueryKey(), queryFn: () => api.fetchSecrets(), options: QueryOptions( isSecure: true, // Data is now handled by the security plugin ), builder: (context, state) { // Data is automatically decrypted when accessed here return Text(state.data?.secretValue ?? ''); },)What happens when isSecure is true?
Section titled “What happens when isSecure is true?”- In-Memory Encryption: If the plugin supports it, data can be encrypted even while sitting in the cache.
- Secure Persistence: If persistence is enabled, data is encrypted before being written to disk.
- Privacy Sanitization: Detailed data is automatically omitted from standard logs (via
FasqLogger). - Lifecycle Protection: By default, secure data is wiped from memory if the app stays in the background for more than 5 minutes (configurable).
Next Steps
Section titled “Next Steps”- Encryption & Keys - How data is protected in transit and at rest.
- Encrypted Persistence - Setting up the secure SQL database.
- Core Security Concepts - General security architecture.
- Fasq Security Model - Platform guarantees, caveats, and key lifecycle details.
- Benchmarks and Limitations - How to validate security and performance tradeoffs in your environment.