How CodexBar Handles Credentials On-Device for Privacy: Secure Keychain Architecture
CodexBar stores all API keys, OAuth tokens, and browser cookies exclusively in the macOS Keychain using generic-password items with restricted SecAccess controls, accessing them without UI prompts while automatically disabling storage for unbundled executables and test environments.
CodexBar implements a privacy-first credential strategy that ensures sensitive data never touches the filesystem. According to the steipete/CodexBar source code, the architecture centers on a three-layer security model that wraps macOS Security framework calls with centralized access gates and test-specific safety blocks.
Centralized Access Control with KeychainAccessGate
The KeychainAccessGate class in Sources/CodexBarCore/KeychainAccessGate.swift serves as the single authority for enabling or disabling all Keychain operations. This design prevents accidental credential exposure across different execution contexts.
Environment-based disabling allows developers to short-circuit Keychain access by setting CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1. When this variable is present, KeychainAccessGate.isDisabled returns true, causing all reads and writes to return errSecInteractionNotAllowed without hitting the Security framework.
Unbundled executable detection automatically disables Keychain access when the binary runs outside an .app bundle. The KeychainPromptCoordinator.disableKeychainForUnbundledExecutableIfNeeded() method calls KeychainAccessGate.forceDisabledForProcess(reason:) to avoid repeated system prompts during CLI development.
For unit testing, KeychainAccessGate.withTaskOverrideForTesting(_:operation:) temporarily enables or disables access for a single async task:
func testTokenCachingWithoutRealKeychain() async throws {
try KeychainAccessGate.withTaskOverrideForTesting(true) {
let key = KeychainCacheStore.Key.oauth(provider: .claude)
XCTAssertEqual(KeychainCacheStore.load(key: key), .missing)
}
}
Test Safety Mechanisms
The KeychainSecurity class in Sources/CodexBarCore/KeychainSecurity.swift acts as the sole entry point to SecItem* functions. Every public method first consults KeychainTestSafety.shouldBlockRealKeychainAccess() to prevent CI pipelines from touching developer Keychains.
The safety check returns true when it detects:
- Test binaries (
swiftpm-testing-helper,.xctestbundles, or XCTest environment variables) - The
CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS=1environment variable
guard !KeychainTestSafety.shouldBlockRealKeychainAccess() else {
return errSecInteractionNotAllowed // Prevents real keychain access during tests
}
This ensures that continuous integration runs never attempt to read from or write to the macOS Keychain.
Secure Storage Implementation
The KeychainCacheStore class in Sources/CodexBarCore/KeychainCacheStore.swift handles all credential persistence. Rather than storing raw tokens on disk, it serializes Codable structs into the Keychain as generic-password items under the service com.steipete.codexbar.cache.
Each entry includes security attributes:
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnlyrestricts access to the current device and requires at least one device unlock- A SecAccess object created by
KeychainCacheStore.cacheAccessControl()that explicitly whitelists only the app bundle and theCodexBarCLIhelper binary
// Store an OAuth token
let tokenKey = KeychainCacheStore.Key.oauth(provider: .claude)
KeychainCacheStore.store(key: tokenKey, entry: myTokenStruct)
// Retrieve with structured result
let result = KeychainCacheStore.load(key: tokenKey) as KeychainCacheStore.LoadResult<MyToken>
switch result {
case .found(let token): use(token)
case .missing: requestNewToken()
case .temporarilyUnavailable: // retry later
case .invalid: // wipe and re-store
}
If Keychain access is disabled or unavailable, the store silently falls back to an in-memory dictionary (implicitTestStore), allowing the app to function without persistence.
No-UI Access Pattern
To prevent macOS password prompts during background operations, KeychainNoUIQuery in Sources/CodexBarCore/KeychainNoUIQuery.swift constructs queries that force immediate failure if the Keychain is locked.
The implementation creates an LAContext with interactionNotAllowed = true and sets the authentication UI policy to kSecUseAuthenticationUIFail:
let context = LAContext()
context.interactionNotAllowed = true
query[kSecUseAuthenticationContext as String] = context
query[kSecUseAuthenticationUI as String] = kSecUseAuthenticationUIFail
When the store loads credentials, it returns a LoadResult enum with cases .found, .missing, .temporarilyUnavailable (for locked Keychains), or .invalid. This design ensures the app handles locked states gracefully without displaying system dialogs.
User Prompting and Privacy Controls
When new credentials must be created, KeychainPromptCoordinator in Sources/CodexBar/KeychainPromptCoordinator.swift displays privacy-focused alerts. The alertModel(for:) method constructs messages that end with the localized keychain_prompt_privacy_note and include a "Learn more" button linking to the project's keychain documentation.
For CLI usage, you can disable Keychain access entirely:
export CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1
./CodexBarCLI --operation
Summary
- Filesystem exclusion: CodexBar never writes raw credentials to disk; all sensitive data lives in the macOS Keychain as generic-password items.
- Access restriction:
KeychainCacheStoreappliesSecAccesscontrols limiting Keychain items to the app bundle andCodexBarCLIbinary. - Safety gates:
KeychainAccessGateprovides centralized enable/disable logic via environment variables and automatic detection of unbundled executables. - Test isolation:
KeychainTestSafetyblocks real Keychain access during unit tests and CI runs unless explicitly overridden. - No-UI policy:
KeychainNoUIQueryforceserrSecInteractionNotAllowedfor locked Keychains, preventing password prompts during background operations.
Frequently Asked Questions
Where does CodexBar store API keys and OAuth tokens?
CodexBar stores all credentials exclusively in the macOS Keychain using the KeychainCacheStore class. Each token is saved as a generic-password item with the service label com.steipete.codexbar.cache and accessibility set to kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly. This ensures credentials are encrypted at rest and bound to the specific device.
How does CodexBar prevent accidental Keychain access during unit testing?
The KeychainSecurity wrapper checks KeychainTestSafety.shouldBlockRealKeychainAccess() before every SecItem* call. This method detects test environments by looking for swiftpm-testing-helper binaries, .xctest bundles, or the CODEXBAR_SUPPRESS_TEST_KEYCHAIN_ACCESS environment variable. When detected, all Keychain operations return errSecInteractionNotAllowed without accessing the real Keychain.
What happens if the macOS Keychain is locked when CodexBar needs credentials?
The KeychainNoUIQuery class configures queries with interactionNotAllowed = true and the kSecUseAuthenticationUIFail policy. If the Keychain is locked, the Security framework returns errSecInteractionNotAllowed, which KeychainCacheStore translates to the .temporarilyUnavailable case. The app can then retry later without displaying a system password prompt.
Can I run CodexBar CLI without allowing Keychain access?
Yes. Set the environment variable CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1 before launching the CLI. This forces KeychainAccessGate.isDisabled to true, causing all credential operations to fail silently with errSecInteractionNotAllowed. Alternatively, running the binary as an unbundled executable automatically triggers KeychainPromptCoordinator.disableKeychainForUnbundledExecutableIfNeeded(), which disables Keychain access to prevent repeated system prompts.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →