How KeychainAccessGate Prevents macOS Keychain Prompts in CodexBar
CodexBar uses a centralized KeychainAccessGate class that evaluates multiple safety checks—from environment variables to task-local overrides—to block keychain access before macOS can display a permission dialog.
The steipete/CodexBar repository implements a robust defense mechanism against intrusive macOS security dialogs. At the center of this system sits KeychainAccessGate, a Swift class defined in Sources/CodexBarCore/KeychainAccessGate.swift that intercepts all keychain access attempts to ensure that the "Keychain wants to access..." prompt never appears at inappropriate times.
The Five-Layer Safety Architecture
The gate implements a hierarchical evaluation strategy that checks multiple conditions before allowing any keychain operation to proceed.
Task-Local Overrides for Testing
Unit tests can inject temporary values without touching the real keychain. The withTaskOverrideForTesting method allows developers to simulate a closed gate for specific code blocks.
When wrapped in this override, any call to KeychainAccessGate.isDisabled returns true for the duration of the task, ensuring that test suites run in isolation from system keychain services.
Environment Variable Lockdown
For CI/CD pipelines and automation, setting CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1 forces the gate closed for the entire process lifetime. This check is evaluated early in Sources/CodexBarCore/KeychainAccessGate.swift at line 39, providing a persistent guard that requires no code changes.
Debug-Only Test Safety
When running under test conditions, the gate automatically invokes KeychainTestSafety.shouldBlockRealKeychainAccess() via the forcesDisabledUnderTests property (line 60). This prevents accidental keychain mutations during test execution, ensuring that integration tests cannot spawn unwanted UI dialogs.
User Defaults Debug Flag
A hidden preference mechanism allows users or developers to toggle keychain access via debugDisableKeychainAccess. Stored in AppGroup defaults and checked at lines 24-28, this setting persists across application launches and can be triggered from the UI or via command-line configuration.
Process-Wide Disable for Unbundled Executables
When CodexBar launches as an unbundled executable (outside a .app bundle), KeychainPromptCoordinator detects this condition and invokes KeychainAccessGate.forceDisabledForProcess(reason:) (lines 95-110 in Sources/CodexBar/KeychainPromptCoordinator.swift). This immediately sets isDisabled to true for the process lifetime, logging a warning and preventing any keychain prompt from appearing.
Implementation in Source Files
All credential providers must consult the gate before displaying UI. For example, the Claude OAuth provider in Sources/CodexBarCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthKeychainAccessGate.swift checks KeychainAccessGate.isDisabled at lines 26-28. If the gate reports disabled, the provider skips the UI entirely, using cached credentials or returning an error instead.
The gate's state is evaluated through the isDisabled computed property, which aggregates all five safety layers into a single boolean decision.
Practical Usage Examples
Disable keychain access globally via environment variable:
export CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1
# All subsequent keychain prompts are silently ignored
Inject a task-local override for unit tests:
KeychainAccessGate.withTaskOverrideForTesting(true) {
// Code that would normally prompt the user
// will see KeychainAccessGate.isDisabled == true
// without touching the real keychain
}
Force disable for unbundled executables:
if KeychainPromptCoordinator.isUnbundledCodexBarExecutable(path) {
KeychainAccessGate.forceDisabledForProcess(reason: "unbundled-executable")
}
Summary
- Task-local overrides allow tests to mock keychain state without system access.
- Environment variables provide CI/CD-friendly global disable switches.
- Debug-only test safety automatically blocks real keychain access during test runs.
- User defaults offer persistent debug toggles for troubleshooting.
- Process-wide disable protects users from prompts when running unbundled binaries.
Frequently Asked Questions
What is KeychainAccessGate?
KeychainAccessGate is a centralized access control class in CodexBar that evaluates multiple safety conditions before allowing any code to interact with the macOS Keychain. It prevents the operating system from displaying "Keychain wants to access..." dialogs by intercepting requests at the application layer.
How do I disable keychain prompts in CI/CD?
Set the environment variable CODEXBAR_DISABLE_KEYCHAIN_ACCESS=1 before launching CodexBar. This forces KeychainAccessGate.isDisabled to return true for the entire process, ensuring that build scripts and automated tests never trigger interactive security dialogs.
Why does CodexBar disable keychain access for unbundled executables?
When the binary runs outside a standard .app bundle, KeychainPromptCoordinator detects this state and calls forceDisabledForProcess(reason:). This prevents keychain prompts from appearing during command-line usage or scripting scenarios where UI interaction is impossible or inappropriate.
Which providers use the KeychainAccessGate?
All OAuth and credential providers in the codebase consult the gate. The Claude OAuth implementation in ClaudeOAuthKeychainAccessGate.swift demonstrates the standard pattern: checking isDisabled before attempting to read or write keychain items, thereby ensuring consistent behavior across the application.
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 →