NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1775 most downloaded on pub.dev
Secure Storage: Encrypted data store optionally secured by biometric lock with support for iOS, Android, MacOS. Partial support for Linux, Windows and web (localStorage).
Last release 1 months ago
25 Aug 2026
Release timing varies
gaps range from 2 weeks to 12 months
Nearly every release is documented
notes for 38 of 42 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
73 releases · first in 2019
android: fix minifyReleaseWithR8 failing in every app that ships a release build. The plugin depended on kotlin-logging, which names every backend it
android: fix minifyReleaseWithR8 failing in every app that ships a release
build. The plugin depended on kotlin-logging, which names every backend it
can bind to, so R8 walked references to ch.qos.logback.* classes that were
genuinely absent and refused to complete:
Missing class ch.qos.logback.classic.Logger (referenced from: ...)
Execution failed for task ':app:minifyReleaseWithR8'
Minification runs in release and nowhere else, so nothing anyone does while
developing reaches it — flutter run, flutter test and an emulator check
all build debug or profile. The first thing to hit it is an attempt to ship
to Play, which is the worst possible moment. Present in 6.0.0-dev.4.
Fixed by removing the dependencies, so nothing needs suppressing. If you
added -dontwarn ch.qos.logback.** to your own proguard-rules.pro to get
6.0.0-dev.4 to build, you can drop it.
android: the plugin's logging now actually produces output. slf4j-api and
kotlin-logging are both facades and neither had a provider, so SLF4J
reported No SLF4J providers were found once and discarded every call after
that. Unless a consuming app happened to ship a binding of its own, this
package has logged nothing at all on Android. It now writes to
android.util.Log under the tag BiometricStorage, and both dependencies
are dropped.
Debug builds log everything. Release builds stay silent until asked:
adb shell setprop log.tag.BiometricStorage VERBOSE
android: BiometricStorageLogging lets an app choose the level and the
destination. level overrides the default above — set it to Log.VERBOSE to
keep verbose logging in a release build without depending on a device
property. sink hands every record to your own logging framework instead of
android.util.Log, with the Throwable passed separately rather than
flattened into the message, so you can report the real exception:
BiometricStorageLogging.sink =
BiometricStorageLogging.Sink { priority, tag, message, throwable ->
// forward to slf4j, Timber, a file appender, a crash reporter
}
Installing a sink turns every level on unless level says otherwise. Both
are optional and the default is unchanged. See the README for the full
slf4j example.
One column per quarter.
Exception codes on BiometricStorageException, the win32 storageFailure path reached by a real store failure, and the integration scaffold that runs th
Exception codes on BiometricStorageException, the win32 storageFailure
path reached by a real store failure, and the integration scaffold that
runs the plugin against real libsecret on CI.
Carries the unreleased 6.0.0-dev.3 fixes too, including the Linux read()
path that leaked a plaintext secret on every call.
BiometricStorageException carries a code. It previously held only a
message, so telling "you called getStorage twice" from "the credential store
failed" meant matching English text — and 6.0.0-dev.2 took the number of
places it is raised from one to six. BiometricStorageExceptionCode is
alreadyInitialized, storageFailure or unknown, and every site that
raises BiometricStorageException classifies itself, including the
AlreadyInitialized the method-channel platforms raise. Additive: the
positional constructor is unchanged and defaults to unknown, so existing
catch blocks keep working. Switch over it with a default — members may be
added in a minor release.
Note the boundary: storageFailure today reaches only Windows. A failing
keychain, keystore or libsecret still surfaces as a raw PlatformException
(SecurityError, Unexpected Error and Security Access Error among
others), because those are not translated. So a single cross-platform "the store failed" branch is
not yet writable; that is a later change.
AuthExceptionCode is documented as an open enum, matching the above. No
behaviour change — but it means the members that Android currently collapses
into unknown, lockout among them, can be split out in a minor release rather
than waiting for 7.0.
Six pre-existing bugs, all found while reviewing 6.0.0-dev.1 and none introduced by it.
Six pre-existing bugs, all found while reviewing 6.0.0-dev.1 and none introduced by it.
androidx.biometric refuses to start after
onSaveInstanceState — logging Unable to start authentication — and returns
without invoking any callback, so the pending Flutter result never completed.
The state is checked up front and reported as
AuthException(AuthExceptionCode.unknown) instead. Reachable whenever the app
is backgrounded, independently of the configuration-change bug below.Activity after a configuration
change. onReattachedToActivityForConfigChanges and
onDetachedFromActivityForConfigChanges were both empty, so after a rotation
every authenticated read or write handed BiometricPrompt a dead
FragmentActivity. ActivityAware documents that the old reference must be
cleared and the new binding adopted; now both happen.PlatformException.code — the field callers match on. The code is now
NotInitialized.init replied twice when an argument was missing or mistyped, so
the caller saw the error and then a success. The success reply now only
happens on the success path.canAuthenticate() reports an unrecognised LAError
as CanAuthenticateResponse.statusUnknown rather than unsupported, matching
Android. unsupported means "the plugin does not support this platform", so a
recoverable biometryLockout was telling callers to give up entirely. Callers
that treat statusUnknown as usable will now attempt authentication where
they previously did not.getStorage() for a name that is already
open no longer rebuilds the store. It used to replace it outright, which threw
away the cached LAContext — so any
darwinTouchIDAuthenticationForceReuseContextDuration in progress — and
quietly adopted whatever options the second call passed. The first call now
wins, as on Android. If you relied on re-initializing to change options, give
each set of options its own store name, or restart — there is no API to close
a store, so none can be reopened differently within a run. Passing different
options to a repeat call was never reported back to Dart, and now definitively
does nothing.forceInit now does what it documents on Windows, web, iOS and
macOS. It was implemented on Android only; the others accepted the flag and
dropped it. It throws BiometricStorageException on every platform — the
PlatformException(code: 'AlreadyInitialized') that the method-channel
platforms raise is translated, so one catch clause covers all of them.
Linux still ignores the flag: its init keeps no per-store state at all,
so implementing it there is a separate change.read() and delete() throw BiometricStorageException
when the credential store fails, instead of returning null and false.
Those values still mean "no value stored" and "there was nothing to delete" —
previously they doubled as the answer for a failing store, so a failure read
as data loss.canAuthenticate() names biometryLockout explicitly rather than
letting it fall through the unmapped-code path, and the nil-error branch
reports statusUnknown too rather than unsupported.iOS/macOS: StorageFileInitOptions.darwinKeychainAccessGroup to store items in a shared keychain access group (kSecAttrAccessGroup), so an app extensio
StorageFileInitOptions.darwinKeychainAccessGroup to store items
in a shared keychain access group (kSecAttrAccessGroup), so an app
extension can read them. Note that the access group is part of an item's
identity — existing items are not migrated automatically.Improve canAuthenticate to include InitOptions to decide for which authenticaiton type to check.
canAuthenticate to include InitOptions to decide for which authenticaiton type to check.Nothing published for this version
* upgrade dependency to web 1.0
enable building on jdk 17 and up https://github.com/authpass/biometric_storage/issues/117 thanks @connyduck
Split Split authenticationValidityDurationSeconds between android and iOS
darwinTouchIDAuthenticationForceReuseContextDuration: Basically the equivalent to androidAuthenticationValidityDurationdarwinTouchIDAuthenticationAllowableReuseDurationNothing published for this version
Nothing published for this version
Add option for iOS/MacOS to allow non-biometric authentication ( darwinBiometricOnly ) #101
darwinBiometricOnly) #101
3.2.Nothing published for this version
Android: (POTENTIALLY BREAKING): Completely removed deprecated old file backend based on androidx.security. This was deprecated since version 3.0.0 an…
promptInfo during read/write thanks @luckyratandroidx.security. This was deprecated since version 3.0.0 and users
should have been migrated on every read or write. (this is only internally, does not change
anything of the API).Build with flutter 3.13, fix macOS build
Build with flutter 3.13, fix macOS build
android: Upgrade AGP, fix building with AGP 8, upgrade all java depen…
android: Upgrade AGP, fix building with AGP 8, upgrade all java depen…
Android: Depend on slf4j-api.
Android: Depend on slf4j-api.
* Add topics to pubspec.yaml
iOS/MacOS: Reuse LAContext to make touchIDAuthenticationAllowableReuseDuration work. thanks @radvansky-tomas
touchIDAuthenticationAllowableReuseDuration work.
thanks @radvansky-tomasAndroid: Move File I/O and encryption to background thread. (Previously used UI Thread) #64
Fix building on all platforms, add github actions to test building.
Android: Remove Moshi dependency altogether. #53
Nothing published for this version
Update to Moshi 1.13 for Kotlin 1.6.0 compatibility. #53
Fixed compile errors with Flutter >= 2.8.0 (Compatible with Flutter 2.5). #47 fix #42
Nothing published for this version
Android: Validate options on int When authenticationValidityDurationSeconds == -1, then androidBiometricOnly must be true
int
When authenticationValidityDurationSeconds == -1, then androidBiometricOnly must be trueauthenticationValidityDurationSeconds is > 0 only show authentication prompt when
necessary. (It will simply try to use the key, and show the auth prompt only when a
UserNotAuthenticatedException is thrown).Nothing published for this version
Please check below for breaking changes in the -rc releases.
-rc releases.Android: Fix a few bugs with authenticationValidityDurationSeconds == -1
authenticationValidityDurationSeconds == -1authenticationValidityDurationSeconds == -1delete if item was not found.unknown exception was thrown instead of userCanceled)androidBiometricOnly prior to Android R (30).AuthExceptionCode.canceledNothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Breaking Change: authenticationValidityDurationSeconds is now -1 by default, which was not supported before hand. If you need backward compatibility,…
Breaking Change: authenticationValidityDurationSeconds is now -1 by default, which was
not supported before hand. If you need backward compatibility, make sure to override this value
to the previous value of 10.
Breaking Change: No more support for Android v1 Plugin registration.
Breaking Change: No longer using androidx.security, but instead handle encryption directly. Temporarily there is a fallback to read old content. This requires either reencrypting everything, or old data will no longer be readable.
authenticationValidityDurationSeconds = -1.BIOMETRIC_WEAK is no longer used, only BIOMETRIC_STRONG.Don't ask for authentication for delete.
Nothing published for this version
Breaking Change: due to the introduction of iOS prompt info there is now a wrapper object PromptInfo which contains AndroidPromptInfo and IosPromptInf…
PromptInfo which contains AndroidPromptInfo and IosPromptInfo.Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
compatibility with kotlin 1.5.20
androidx.security:security-crypto from 1.1.0-alpha02 to 1.1.0-alpha03
Handle android BIOMETRIC_STATUS_UNKNOWN response on older devices (Android 9/API 28(?))
BIOMETRIC_STATUS_UNKNOWN response on older devices
(Android 9/API 28(?))* Null safety stable release.
* Null safety migration.
Upgrade to latest Android dependencies (gradle plugin, androidx.*, gradle plugin)
upgrade android moshi dependency.
Nothing published for this version
Support for web support: Warning: Unencrypted - stores into local storage on web!
Nothing published for this version
Nothing published for this version
* Fix windows plugin config.
Workaround to not load win32 when compiling for web.
Windows: Initial support for windows. only unauthenticated storage in Credential Manager.
Linux: Initial support for Linux - only unauthenticated storage in Keyring.
Android: allow customization of the PromptInfo (labels, buttons, etc). @patrickhammond
Android: on error send stack trace to flutter. also fixed a couple of warnings.
Android: updated dependencies to androidx.security, biometric, gradle tools.
Your coding agent can read these notes before it upgrades. Set up the MCP server →