How CodexBar's Keychain Access System Retrieves Browser Cookies on macOS
CodexBar retrieves browser cookies by executing non-interactive Keychain reads to obtain the browser's encryption key, decrypting the AES-256-GCM protected SQLite cookie database, and caching the resulting HTTP headers in a dedicated Keychain item for fast reuse.
CodexBar, an open-source macOS menu bar application maintained by steipete/CodexBar, implements a sophisticated Keychain access system to authenticate with AI providers like OpenAI and Claude without requiring manual API key entry. The system extracts the encryption key that browsers store in the macOS Keychain, uses it to decrypt the local Cookies SQLite database, and transforms the encrypted values into standard HTTP Cookie headers.
The Seven-Step Cookie Retrieval Pipeline
The CodexBar Keychain access system follows a deterministic pipeline to move from raw Keychain data to usable authentication headers.
Step 1: Locating the Browser's Safe Storage Entry
CodexBar prioritizes Chrome when retrieving credentials. It queries the macOS Security Framework for the "Chrome Safe Storage" entry, falling back to Safari's equivalent storage if Chrome is unavailable. This logic resides in KeychainPromptCoordinator.swift, which builds the user-facing alert model while the underlying system locates the storage item.
Step 2: Non-Interactive Keychain Reads
To avoid interrupting the user with system dialogs, CodexBar performs all Keychain operations with kSecUseAuthenticationUIFail. This flag instructs SecItemCopyMatching to return an error rather than prompt for authentication if the Keychain is locked.
In KeychainCacheStore.swift, the wrapper calls SecItemCopyMatching with kSecAttrAccessibleAfterFirstUnlock and kSecUseAuthenticationUIFail, ensuring the app reads the internet-password item containing the browser's master key without UI interaction. If the OS requires authentication, the read fails silently and CodexBar presents a friendly alert.
Step 3: Deriving the AES-256 Encryption Key
The raw bytes retrieved from the Keychain represent the master key used by Chromium's "OS-crypt" implementation. ChromeCookieKeyProvider.swift transforms this payload into a usable AES-256-GCM key following the public Chromium specification (as implemented in os_crypt.cc). This cryptographic key is required to decrypt the individual cookie values stored in the browser's SQLite database.
Step 4: Querying the SQLite Cookie Database
With the encryption key in hand, ChromeCookieImporter.swift opens the browser's Cookies file (located at <profile>/Cookies or <profile>/Network/Cookies in newer versions) using SQLite. The code executes a targeted SELECT statement that filters rows by host_key, retrieving only cookies matching the specific provider domain (e.g., *.openai.com or *.claude.ai).
Step 5: Decrypting Cookie Values
For each row returned by the database query, the encrypted_value column contains AES-256-GCM encrypted data. ChromeCookieImporter.swift decrypts these values using the key derived in Step 3, producing plaintext strings like session=abc123; path=/; domain=.openai.com.
Step 6: Caching Headers in the Keychain
To eliminate repeated decryption overhead and reduce database access, CodexBar stores the assembled HTTP header string in its own Keychain item under the service identifier com.steipete.codexbar.cache. The CookieHeaderCache.swift module writes the header to an account named cookie.<provider> (e.g., cookie.openai), enabling fast, read-only retrieval for subsequent requests until the session expires.
Step 7: Providing Headers to API Providers
When a provider implementation (such as OpenAIWebProvider.swift or ClaudeOAuthProvider.swift) requires authentication, it calls CookieHeaderCache.load(provider:). If a valid cached entry exists, it is injected directly into the HTTP request; otherwise, the full import pipeline triggers automatically.
Security Configuration and Browser Fallback
The Keychain access system implements several security-first policies to balance functionality with user privacy.
Read-Only, Non-Interactive Design. All Keychain reads use kSecUseAuthenticationUIFail. If the system cannot return the key without UI (for example, if the user has locked their Keychain), CodexBar aborts the import and displays a preferences alert rather than forcing a system dialog.
Browser Fallback Order. The import logic attempts Chrome first, then Chromium-based variants, then Safari. The code walks this list sequentially and stops at the first readable store, ensuring maximum compatibility without unnecessary Keychain queries.
Granular User Controls. Users can disable Keychain access entirely via Preferences → Advanced → Disable Keychain Access, stored in Settings.swift as the disableKeychainAccess boolean. Individual providers can also implement per-domain prompt policies.
Implementation Examples
Importing Chrome Cookies for a Provider
import CodexBar
/// Import a cookie header for the given provider domain.
func importChromeCookie(for provider: Provider) async throws -> String {
// 1️⃣ Locate the Chrome Safe Storage entry.
let rawKey = try KeychainCacheStore.readInternetPassword(
service: "Chrome Safe Storage"
)
// 2️⃣ Derive the AES‑GCM key.
let cryptoKey = ChromeCookieKeyProvider.key(from: rawKey)
// 3️⃣ Open the Chrome profile's Cookies DB.
let importer = ChromeCookieImporter(profilePath: .defaultChrome, key: cryptoKey)
// 4️⃣ Pull & decrypt the matching cookies.
let header = try await importer.cookieHeader(for: provider.cookieDomain)
// 5️⃣ Cache the result for later fast reads.
CookieHeaderCache.store(provider: provider, cookieHeader: header, sourceLabel: "Chrome")
return header
}
Key files referenced: KeychainCacheStore.swift, ChromeCookieKeyProvider.swift, ChromeCookieImporter.swift, CookieHeaderCache.swift.
Using a Cached Cookie Header
import CodexBar
func makeRequest(to endpoint: URL, using provider: Provider) async throws -> Data {
// Load a cached header; if nil, start an import.
let header = CookieHeaderCache.load(provider: provider) ??
try await importChromeCookie(for: provider)
var request = URLRequest(url: endpoint)
request.addValue(header, forHTTPHeaderField: "Cookie")
let (data, _) = try await URLSession.shared.data(for: request)
return data
}
Key file referenced: CookieHeaderCache.swift.
Disabling Keychain Access Programmatically
import CodexBar
/// Turn off all keychain reads for the running instance.
func disableKeychainAccess() {
Settings.shared.disableKeychainAccess = true
// The next import will short-circuit and show an alert.
}
Key file referenced: Settings.swift.
Summary
- Non-interactive retrieval: CodexBar uses
SecItemCopyMatchingwithkSecUseAuthenticationUIFailto read browser keys from the macOS Keychain without prompting the user. - AES-256-GCM decryption: The system derives the Chromium master key from Keychain data and uses it to decrypt cookies from the SQLite
Cookiesdatabase. - Intelligent caching: Decrypted headers are stored in
com.steipete.codexbar.cacheto eliminate redundant database access and cryptographic operations. - Browser flexibility: The implementation supports Chrome, Chromium variants, and Safari through a prioritized fallback mechanism.
- User control: Global and per-provider settings allow users to disable Keychain access entirely via
Settings.swift.
Frequently Asked Questions
Is CodexBar's Keychain access safe for my browser data?
Yes. The CodexBar Keychain access system operates read-only and never modifies browser databases. It uses standard macOS Security Framework APIs with kSecUseAuthenticationUIFail to prevent unauthorized access attempts, and caches decrypted headers only in a dedicated Keychain item (com.steipete.codexbar.cache) separate from browser storage.
Why does CodexBar need to access the "Chrome Safe Storage" Keychain item?
Modern browsers encrypt their cookie databases using a master key stored in the macOS Keychain under names like "Chrome Safe Storage." CodexBar must read this key via SecItemCopyMatching in KeychainCacheStore.swift to derive the AES-256-GCM key required to decrypt the encrypted_value columns in the browser's SQLite database.
What happens if I deny Keychain access or disable it in preferences?
If Keychain access is disabled via Settings.shared.disableKeychainAccess or the system denies the read, CodexBar aborts the import pipeline and displays a preferences alert. The app cannot retrieve browser cookies without this access, meaning users must either enable Keychain access or manually provide authentication credentials through other means.
Does CodexBar support retrieving cookies from browsers other than Chrome?
Yes. While CodexBar prioritizes Chrome, the system implements a browser fallback order (Chrome → Chromium-based → Safari) within the import logic. If ChromeCookieImporter.swift cannot locate a Chrome profile, the system attempts to read from Safari's Safe Storage, ensuring compatibility across the major macOS browsers.
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 →