IronVault is an offline-first private vault built with Flutter.
It stores vault data locally on the device and protects it with strong encryption and app-level authentication.
- Local-first vault for passwords and sensitive records
- Master PIN authentication with optional biometric unlock
- Welcome screen plus dedicated keypad-based PIN unlock flow
- Encrypted storage for vault entries
- Onboarding focused on local privacy, secure unlock, and recovery-key safety
- Android document scan/import support
- Add-item draft restore to preserve unsaved progress after lock/interruption
- Manual and startup update checks via GitHub Releases
- In-app privacy, update, issue-reporting, project-license, and share-app links from the About screen
- Vault item types:
- Passwords
- Bank accounts
- Cards
- Secure notes
- Documents
- Search and filtering
- Category support with rename propagation across existing saved items
- Password health scoring with actionable review cards for weak, reused, and old passwords
- Auto-lock with configurable timer and app-switch behavior
- Recovery key flow for PIN recovery with protected reveal
- Recovery key setup that can be resumed until the user confirms it has been saved
- Recovery key management from Settings with re-authentication and manual in-screen generation
- PIN retry cooldown after repeated failed attempts
- New-item draft restore and keep/discard draft prompt on exit
- Encrypted backup restore plus CSV password import/export
- Pull-to-refresh on Vault, Search, and Password Health screens
- One-tap deep links from Password Health into filtered affected items
- Vault data is encrypted before storage
- Master PIN is stored as a hash, not plain text
- Optional biometric auth uses platform APIs
- IronVault does not use cloud sync
- Recovery key is hidden by default and requires re-authentication before reveal
- Recovery key reveal supports biometrics or PIN fallback
- Recovery key raw value is only kept temporarily until the user confirms it has been saved
- Repeated wrong PIN attempts trigger a persistent cooldown
- Clipboard clearing is supported for copied sensitive fields
- Android screenshot and recents-preview protection is enabled at the activity level
- Screenshot/privacy behavior can still vary by platform and OEM implementation
- Sentry crash reporting is enabled for release builds with safe metadata capture
This repository is licensed under MIT for source code reuse as defined in LICENSE.
Important:
- The MIT license covers code.
- The project name IronVault, logo, icon, and brand assets are not granted as a trademark license.
- If you fork or redistribute, use your own app name, package ID, and branding.
- Flutter
- Dart
- Riverpod
- Drift (SQLite) for vault items
- sqflite for category storage
- flutter_secure_storage
- local_auth
- AES-based encryption utilities
- Android: supported
- iOS: code exists but not production-validated in this repo
flutter pub get
flutter runAPK:
flutter build apk --releaseAAB:
flutter build appbundle --releaseOutput paths:
build/app/outputs/apk/release/ironvault-v<version>.apkbuild/app/outputs/bundle/release/app-release.aab
Version is maintained in pubspec.yaml:
versionNamecomes fromversionversionCodecomes from the build number suffix
Use Git tags for releases:
- Tags follow the app version format in
pubspec.yaml(for examplev1.0.17).
Workflows live under .github/workflows/.
- Flutter Analyze runs on every push and pull request to
main: checks out the repo, runsflutter pub get, thenflutter analyze.
- Release APK runs when you push a tag whose name starts with
v(for examplev1.0.17). - The job restores Android release signing from repository secrets (never committed): base64-decoded keystore under
android/app/keystore.jksandandroid/key.propertiesgenerated in the runner. - It runs
flutter build apk --release, stages the release artifact asironvault-<tag>.apk(preferring the Gradleapk/releaseoutput when present), runs a short verify step (apksigner/aaptwhen available), then creates or updates a GitHub Release for that tag and uploads the APK. - Release notes for the GitHub Release are taken from
CHANGELOG.md: the workflow looks for a section whose heading is exactly##plus the tag name (for example## v1.0.17). Add that section before you push the tag so the release page is populated.
Configure these in GitHub → Settings → Secrets and variables → Actions:
| Secret | Purpose |
|---|---|
ANDROID_KEYSTORE_BASE64 |
Keystore file, base64-encoded (used only in CI, not stored in git) |
ANDROID_KEYSTORE_PASSWORD |
Keystore password |
ANDROID_KEY_ALIAS |
Signing key alias |
ANDROID_KEY_PASSWORD |
Signing key password |
- Update
versioninpubspec.yaml. - Add a matching section to
CHANGELOG.md, for example## v1.0.17(must match the tag you will push). - Commit and push to
main. - Create and push the tag (for example
git tag -a v1.0.17 -m "v1.0.17"thengit push origin v1.0.17). - Confirm the Release APK workflow on the Actions tab completed; download
ironvault-v1.0.17.apkfrom Releases.
For a local signed release build, keep using android/key.properties and your keystore as described in Security Rules For Contributors below; do not commit those files.
The app can check GitHub Releases and tell you when a newer version is available. That flow is independent of Actions: it compares your installed version to published releases.
lib/
core/
data/
features/
.github/
workflows/
android/
ios/
assets/
Never commit signing credentials or keystores:
android/app/keystore.jksandroid/key.properties*.keystore*.jks.env.env.*android/app/google-services.jsonios/Runner/GoogleService-Info.plistandroid/local.properties
dart format .
flutter analyze- Some platform behaviors (recents preview/privacy handling) can vary by OEM launcher and Android version.
- Biometric availability depends on device hardware and enrollment state.
- Auto-lock timer currently applies to app background/resume behavior, not true on-screen idle timeout.
- Autofill service integration is currently disabled/limited by design decisions in this project stage.
- Categories still use a separate local database path from the main vault items.
This repository is not a Play Store submission package and does not claim Play Store policy compliance by default.