NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
AppPlayer security library (merged) — domain-neutral primitives (SIGN/STORE/CRYPTO/TRUST/AUDIT/MAUTH/BIO) + AppPlayer domain layer (roles/events/facade).
Last release 2 months ago
01 Aug 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 4 of 4 stable releases
Nothing withdrawn
no release was ever pulled
3 months old
4 releases · first in 2026
One column per month.
SecureStorage.listKeys failed on macOS with errSecParam (-50) on every call, while read / write / delete / exists on the same vault worked. Reported f
SecureStorage.listKeys failed on macOS with errSecParam (-50) on every
call, while read / write / delete / exists on the same vault worked.
Reported from live Studio QA, where secret.list had never once succeeded.
Cause. Enumeration went through the plugin's readAll, which asks the
keychain for kSecMatchLimitAll together with kSecReturnData. A
file-based keychain rejects that combination; only the data-protection
keychain accepts it. This backend runs on the file-based login keychain by
choice — MacOsOptions(useDataProtectionKeyChain: false), so an ad-hoc
signed dev build can use the keychain without a paid signing identity. The
limitation is therefore permanent for this backend, not a transient plugin
bug. Single-key operations never touch that query shape, which is why only
listing broke.
wipeNamespace used the same call and was broken the same way. Nothing had
exercised it.
Fix. The backend keeps its own index of the keys it has written.
listKeys and wipeNamespace read the index; neither calls readAll any
more. Listing also stops asking for far more than it needs — it used to pull
every stored plaintext to return a list of names, which on macOS can raise a
per-item ACL prompt even where the query succeeds.
FlutterSecureStorageBackend.keyIndexSeeded — whether the index was seeded
from the store's own contents. False means enumeration was unavailable when
the index was first needed, so entries written by an earlier version are
not listed. A caller that must not act on a partial view (a migration, a
reset that reports what it will delete) should check it rather than treat
listKeys as exhaustive. It sits on the concrete backend, not on the
SecureStorage port: adding a member to the port would break every existing
implementation, and the property describes this platform binding.On macOS, keys written before this version cannot be adopted into the
index — reading their names is the very call that fails — so they will not
appear in listKeys. Everything written from this version on is listed.
wipeAll() also makes the index exhaustive again. On every other platform the
index is seeded from the existing store on first use and nothing is lost.
No public API change. Every name keeps its spelling and its call form; import 'package:appplayer_secure/appplayer_secure.dart' still resolves all of t
No public API change. Every name keeps its spelling and its call form;
import 'package:appplayer_secure/appplayer_secure.dart' still resolves all of
them. Existing consumers upgrade with no code edit.
The domain-neutral primitives (SIGN · STORE · CRYPTO · TRUST ·
AUDIT · MAUTH · BIO, shared types and errors, role enums, event
catalog, both sealers) moved to the new pure-Dart package
appplayer_secure_core, which this package depends on and re-exports.
This package keeps what needs Flutter: FlutterSecureStorageBackend,
DefaultBiometricAdapter, AppPlayerRootCAs (including fromAsset) and the
AppPlayerSecure facade.
The split exists so a headless host can use the primitives. This package
declares flutter, flutter_secure_storage and local_auth, which a
Dart-only image cannot resolve — and no arrangement of entry points changes
that, because resolution follows the pubspec, not the imports.
UnavailableBiometricAdapter (via the core) — reports biometrics as
unavailable and refuses every authentication.PassphraseSealer — seals/unseals a Map under an operator passphrase (PBKDF2-HMAC-SHA256, 210k iterations → ChaCha20-Poly1305 AEAD), producing a portab
PassphraseSealer — seals/unseals a Map<String, String> under an operator
passphrase (PBKDF2-HMAC-SHA256, 210k iterations → ChaCha20-Poly1305 AEAD),
producing a portable, opaque base64 blob with the KDF salt + AEAD nonce
embedded. Unlike AtRestSealer — whose symmetric key lives only in the
machine keychain and cannot leave the device — the key is derived purely from
the passphrase, so a sealed blob can be migrated to another machine and
reopened with the same passphrase (e.g. operational-credential portability).
Exported from the barrel. Additive — no existing surface changed.Domain-neutral security primitives: signature · secure_storage · cryptography · trust_chain · audit · mutual_auth · biometric, plus shared types / err
signature · secure_storage ·
cryptography · trust_chain · audit · mutual_auth · biometric,
plus shared types / error.roles (SignerRole / TrustRole + MakeMind Root CA
registry), events (AuditEvent catalog), AppPlayerSecure facade.secure primitives and appplayer_secure
domain wrapper into one package.Your coding agent can read these notes before it upgrades. Set up the MCP server →