secure_key_manager 1.1.0 copy "secure_key_manager: ^1.1.0" to clipboard
secure_key_manager: ^1.1.0 copied to clipboard

Fetch secret keys by name from Firebase Cloud Functions backed by Google Secret Manager. No secrets ever ship in your app binary, repo, or .env.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:secure_key_manager/secure_key_manager.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // No FlutterFire CLI, no firebase_options.dart, no google-services.json /
  // GoogleService-Info.plist. Just paste the config from the Firebase Console
  // (Project settings → Your apps → SDK setup and configuration) here.
  await SecureKeyManager.initialize(
    firebaseOptions: const FirebaseOptions(
      apiKey: 'YOUR_API_KEY',
      appId: 'YOUR_APP_ID',
      messagingSenderId: 'YOUR_SENDER_ID',
      projectId: 'YOUR_PROJECT_ID',
    ),
    region: 'asia-south1', // your Cloud Functions region
    cacheTtl: const Duration(minutes: 30),
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'secure_key_manager demo',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.indigo),
      home: const KeyDemoPage(),
    );
  }
}

class KeyDemoPage extends StatefulWidget {
  const KeyDemoPage({super.key});

  @override
  State<KeyDemoPage> createState() => _KeyDemoPageState();
}

class _KeyDemoPageState extends State<KeyDemoPage> {
  static const _keys = [
    'AGORA_APP_ID',
    'GOOGLE_MAPS_KEY',
    'OPENAI_API_KEY',
  ];

  String _keyName = _keys.first;
  String _status = 'Pick a key and tap Fetch.';
  bool _loading = false;

  Future<void> _fetch() async {
    setState(() {
      _loading = true;
      _status = 'Fetching $_keyName…';
    });
    try {
      final value = await SecureKeyManager.get(_keyName);
      // Never print real secrets in production logs — masked here for the demo.
      final masked = value.length <= 4
          ? '••••'
          : '${value.substring(0, 2)}••••${value.substring(value.length - 2)}';
      setState(() => _status = '$_keyName = $masked (len ${value.length})');
    } catch (e) {
      setState(() => _status = 'Error: $e');
    } finally {
      setState(() => _loading = false);
    }
  }

  Future<void> _logout() async {
    await FirebaseAuth.instance.signOut();
    SecureKeyManager.clearCache();
    setState(() => _status = 'Signed out and cache cleared.');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('SecureKeyManager')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            DropdownButton<String>(
              value: _keyName,
              isExpanded: true,
              items: _keys
                  .map((k) => DropdownMenuItem(value: k, child: Text(k)))
                  .toList(),
              onChanged: _loading
                  ? null
                  : (v) => setState(() => _keyName = v ?? _keyName),
            ),
            const SizedBox(height: 16),
            FilledButton(
              onPressed: _loading ? null : _fetch,
              child: _loading
                  ? const SizedBox(
                      height: 18,
                      width: 18,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Text('Fetch key'),
            ),
            const SizedBox(height: 8),
            OutlinedButton(
              onPressed: _loading ? null : () => SecureKeyManager.evict(_keyName),
              child: Text('Evict $_keyName from cache'),
            ),
            const SizedBox(height: 8),
            OutlinedButton(
              onPressed: _loading ? null : _logout,
              child: const Text('Logout (clear cache)'),
            ),
            const SizedBox(height: 24),
            Text(_status, style: Theme.of(context).textTheme.bodyLarge),
          ],
        ),
      ),
    );
  }
}
0
likes
150
points
13
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Fetch secret keys by name from Firebase Cloud Functions backed by Google Secret Manager. No secrets ever ship in your app binary, repo, or .env.

Topics

#firebase #secrets #security #secret-manager #cloud-functions

License

MIT (license)

Dependencies

cloud_functions, firebase_auth, firebase_core, flutter

More

Packages that depend on secure_key_manager