Keybay on macOS
macOS has two V2 host profiles. Both use the common encrypted framed file and one Keychain root. The process’s signed application identifier selects the entitled profile; absence selects the ordinary unentitled profile. Keybay does not retry the other profile after an operation fails.
Protection at a glance
Entitled app: App-bound key
CLI / unentitled app: Account-level
- Key access: the entitled profile uses a signed Keychain group. The ordinary profile uses the login Keychain; its declared namespace does not authenticate the calling application.
- File isolation: entitled apps need App Sandbox for container isolation. An unsandboxed app’s private file permissions do not isolate it from its own user.
- Hardware assurance: neither generic Keychain root carries a Secure Enclave claim.
- Additional methods: optional passphrase/passkeys; recommended for high-value records in the account-level profile. Any one enrolled method plus the platform root is required when methods exist.
- Main limitation: signed-group key access and file sandboxing are separate. Login-Keychain ACLs are not a portable application-isolation guarantee.
These are key-access levels, not hardware ratings or protection against a compromised host process. See security levels for the exposure per attacker.
Requirements
For the entitled profile, the running app needs its signed application
identifier and matching Data Protection Keychain access. Enable App Sandbox
when the app also needs file isolation. Ordinary executables declare their
namespace in the owning pubspec or embed it with keybay_compile, and need
access to the effective account’s login Keychain. Release binaries also need
the packaging qualification below.
Signed and entitled application
Keybay derives the application identifier from the code signature and checks
it against the bundle identifier. The encrypted file lives in the app container
when App Sandbox is enabled, otherwise in a derived Application Support
directory. One stable random root is stored in the exact signed Data Protection
Keychain group, non-synchronizing and WhenUnlockedThisDeviceOnly.
The entitlement protects root access from processes outside the signed group.
It does not by itself sandbox the file; App Sandbox is a separate protection.
Keychain state can survive loss of the application container. If a reinstall,
restore or interrupted initialization leaves a root without a complete file,
open() returns storeStateConflict. Use the SDK’s deliberate recovery
procedure; do not reset solely because an error
occurred. Physical reinstall/restore and entitlement transitions need their
own qualification.
Explicitly authorized same-team apps may share a group. Keybay therefore makes no absolute per-app or Secure Enclave claim. See Apple’s access-group model.
CLI and unentitled application
An ordinary executable declares its namespace in the owning pubspec or embeds
it with keybay_compile. The encrypted file lives in a restrictive derived
Application Support directory. One identity-derived root item lives in the
effective account’s explicit login Keychain,
~/Library/Keychains/login.keychain-db. Keybay never uses the default
Keychain or search list instead: if that file is missing, as for an SSH-only
account, root, or a CI host with a custom default Keychain, opening fails with
platformProtectorUnavailable before any Keychain item is read or written.
Classic file Keychains cannot reliably suppress UI for one native call.
Opening, changing authentication, and resetting may therefore show trusted
Keychain UI. Keybay rejects interaction-forbidden root acquisitions before
calling the Keychain. Record operations use the session’s store key and never
contact the provider. If a changed file cannot be authenticated with that key,
the error remains storeAuthenticationFailed instead of inferring a peer
authentication change.
This profile is namespaceOnly: the declaration is not authenticated by the
OS. Keychain ACL behavior can add protection for a stable signed executable,
but dart run, unsigned/ad-hoc builds, binary replacement, and invoking a
trusted CLI do not form one portable application sandbox. Another same-user
process may also modify the application files.
Use a Keybay passphrase or passkey for passwords and other high-value records. Either method keeps the store key unavailable from the login-Keychain item and encrypted file alone. It cannot prevent an authorized same-user actor from deleting or replacing those artifacts.
Hardened AOT packaging
The SDK’s compile helper can produce a native module:
dart run keybay:keybay_compile --aot-snapshot bin/app.dart -o build/app.aot
Package it with a dedicated copy of the matching SDK’s dartaotruntime. Sign
both files with the same Developer ID team, hardened runtime and secure
timestamps, then launch the runtime with the module’s absolute path. Keep
library validation enabled; the qualified pair needs no entitlement exceptions.
The namespace remains the declaration embedded in the application module.
The repeatable macos-developer-id lane passed native execution, passphrase
protection, replacement by a distinct signed module, and exact Keychain/file
cleanup. An ad-hoc module was separately rejected by the hardened runtime’s
library validation. This covers the unentitled profile on the tested Mac;
notarization and entitled-app distribution are separate evidence.
On Dart 3.12.2/macOS 26.2 arm64, a hardened single-file dart compile exe
output is killed before startup. Its appended-image loader copies executable
pages into anonymous memory; a separate module uses the native loader. The
review brief records the reproduction and source analysis.
The product CLI reproduced the hardened single-file failure on Dart 3.13.4.
Separate signed runtime/module fixtures passed startup and protected-store
upgrade checks, but the production archive, installed launcher, Homebrew
upgrade and downloaded/notarized artifact still need qualification. This is an
active CLI release gate; see release readiness.
Limitations
The two profiles use the same authenticated encryption. Their difference is the OS authority required to access the platform root. An entitled key does not sandbox the encrypted file, and an account-level passphrase does not create an OS-authenticated application identity. Both retain the shared threat model: no protection against a compromised host process, plaintext after disclosure, deletion or rollback. Keybay does not add a per-read biometric or user-presence prompt.
Recovery
If a retained root, missing file or changed identity produces a conflict, use
the SDK’s deliberate recovery procedure.
Keybay.reset() intentionally abandons the managed store; it cannot recover
values. Do not reset automatically after an access error or profile change.
No fallback or migration
Entitled and unentitled profiles have different identity/file/provider commitments. A missing entitlement, inaccessible group, Keychain access failure, changed signature, missing root, or mismatched retained item fails closed. V2 does not probe or migrate pre-V2 state and never falls back between profiles.
Qualification
Real login-Keychain integration exercises the unentitled profile. A signed Flutter harness exercises the entitled Data Protection profile. Exact device and lifecycle qualification is tracked in the qualification record.