voo_secrets 1.0.0
voo_secrets: ^1.0.0 copied to clipboard
Secure runtime secrets management for Flutter. Fetches secrets from your backend after authentication - secrets never exist in your app binary.
VooSecrets #
Secure runtime secrets management for Flutter. Fetches secrets from your backend after authentication - secrets never exist in your app binary.
Why VooSecrets? #
Unlike build-time solutions that embed secrets in your app, VooSecrets:
| Feature | Build-Time (voo_config) | Runtime (VooSecrets) |
|---|---|---|
| Secrets in binary | Yes | Never |
| Requires auth | No | Yes |
| Server revocation | No | Yes |
| Scoped access | No | Yes |
| Rotation without update | No | Yes |
This is the only way to have truly secure secrets in a client app.
Features #
- Never in Binary - Secrets fetched at runtime, not compiled in
- Auth Required - Only authenticated users can access secrets
- Secure Storage - Uses platform Keychain/Keystore for caching
- Scoped Access - Different users can have different secrets
- Auto Refresh - Automatically refreshes before expiry
- Revocation - Revoke access server-side without app update
Installation #
dependencies:
voo_secrets: ^1.0.0
Quick Start #
1. Set up your backend #
Choose a reference implementation from backends/:
2. Initialize in your app #
import 'package:voo_secrets/voo_secrets.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await VooSecrets.initialize(
config: SecretsConfig(
endpoint: 'https://your-backend.com/api/secrets',
tokenProvider: () async => authService.getAccessToken(),
),
);
runApp(MyApp());
}
3. Fetch secrets after login #
// After user authenticates
await VooSecrets.instance.fetchSecrets();
4. Access secrets #
// Get a secret
final stripeKey = VooSecrets.instance.get<String>('stripe_api_key');
final maxRetries = VooSecrets.instance.get<int>('max_retries');
// Check if exists
if (VooSecrets.instance.has('premium_api_key')) {
// User has premium access
}
// Require a secret (throws if missing)
final dbUrl = VooSecrets.instance.require<String>('database_url');
5. Clear on logout #
await VooSecrets.instance.clear();
API Reference #
SecretsConfig #
| Parameter | Type | Default | Description |
|---|---|---|---|
endpoint |
String |
required | URL to fetch secrets from |
tokenProvider |
Future<String?> Function() |
required | Returns auth token |
refreshBuffer |
Duration |
5 minutes | Time before expiry to refresh |
autoRefresh |
bool |
true | Auto-refresh on access |
timeout |
Duration |
30 seconds | Request timeout |
VooSecrets Methods #
| Method | Description |
|---|---|
fetchSecrets() |
Fetch secrets from backend |
refreshIfNeeded() |
Refresh if expired or expiring soon |
get<T>(key) |
Get secret value (returns null if missing) |
require<T>(key) |
Get secret value (throws if missing) |
has(key) |
Check if secret exists |
clear() |
Clear all secrets (call on logout) |
VooSecrets Properties #
| Property | Type | Description |
|---|---|---|
status |
SecretStatus |
Current status |
hasSecrets |
bool |
Whether secrets are loaded |
needsRefresh |
bool |
Whether refresh is needed |
keys |
Set<String> |
All secret keys |
scopes |
List<String> |
User's access scopes |
expiresAt |
DateTime? |
When secrets expire |
Backend API Contract #
Your backend must implement:
GET /api/secrets
Authorization: Bearer <token>
Response 200:
{
"secrets": {
"stripe_api_key": "sk_live_...",
"database_url": "postgres://..."
},
"expiresAt": "2024-01-15T12:00:00Z",
"scopes": ["read:secrets", "premium"]
}
Response 401: Unauthorized
Response 403: Insufficient permissions
Custom Storage #
By default, VooSecrets uses flutter_secure_storage. You can provide custom storage:
await VooSecrets.initialize(
config: config,
storage: MyCustomStorage(), // implements SecretsStorage
);
Testing #
Use MockSecretsService for tests:
await VooSecrets.initialize(
config: config,
service: MockSecretsService.withSecrets({
'api_key': 'test-key',
}),
storage: MemorySecretsStorage(),
);
Security Best Practices #
- Always use HTTPS for your secrets endpoint
- Validate tokens on your backend
- Implement rate limiting to prevent abuse
- Log access for audit trails
- Rotate secrets regularly
- Use short expiry times (1 hour recommended)
- Scope secrets - don't give all users all secrets
License #
MIT License - see LICENSE file for details.
Built by VooStack #
Need help with Flutter security or custom backend solutions?
VooStack builds enterprise Flutter applications and developer tools.