# Security Implications of Storing API Keys in CodexBar: Risks and Mitigations

> Discover the security risks of storing API keys in CodexBar. Learn how plaintext storage in memory exposes keys and explore essential mitigation strategies to protect your sensitive data.

- Repository: [Peter Steinberger/CodexBar](https://github.com/steipete/CodexBar)
- Tags: deep-dive
- Published: 2026-07-08

---

**CodexBar stores LLM provider API keys as plain-text strings in memory after reading them from environment variables or unencrypted JSON configuration files, exposing them to disk leakage, subprocess environment inheritance, and potential memory extraction.**

CodexBar is an open-source macOS menu bar application that integrates multiple LLM providers into a unified interface. Understanding the **security implications of storing API keys in CodexBar** is critical for developers, as the application implements a token-driven architecture that persists credentials in readable formats and inherits standard process security limitations.

## How CodexBar Reads and Stores API Keys

The token resolution system centers around **SettingsReader** structs and the **ProviderTokenResolver** class. According to the steipete/CodexBar source code, credentials are sourced from three distinct locations:

1. **Environment variables** – Each provider defines specific keys such as `OPENAI_API_KEY` or `VENICE_API_KEY` in [`OpenAIAPISettingsReader.swift`](https://github.com/steipete/CodexBar/blob/main/OpenAIAPISettingsReader.swift) (lines 3-10) and [`VeniceSettingsReader.swift`](https://github.com/steipete/CodexBar/blob/main/VeniceSettingsReader.swift) (lines 4-10), accessed via the static `apiKey(environment:)` method.

2. **User-wide configuration** – The `~/.codexbar/config.json` file is parsed at application startup by [`CLIDiagnoseCommand.swift`](https://github.com/steipete/CodexBar/blob/main/CLIDiagnoseCommand.swift) (line 265), with values falling back to the same environment helper methods.

3. **Provider-specific overrides** – Files such as [`.codexbar/provider-config.json`](https://github.com/steipete/CodexBar/blob/main/.codexbar/provider-config.json) are merged into the environment dictionary before any `SettingsReader` is consulted.

The **ProviderTokenResolver** (lines 190-260) then determines which token takes precedence for each request, storing the final value as a standard Swift `String` in process memory.

## Critical Security Vulnerabilities

### Plain-Text Storage on Disk

The JSON configuration file is written without encryption. If the user's home directory backs up to cloud services, API keys travel with the backup unencrypted. Additionally, any process running under the user's UID can read `~/.codexbar/config.json`, enabling malicious scripts to exfiltrate credentials directly from the filesystem.

### Environment Variable Leakage

When CodexBar spawns subprocesses, the full environment is inherited by default. Child processes that log their environment or crash and write core dumps may expose keys. While `UsageStore+APIKeyDebug.swift` (line 19) implements scrubbing logic to remove sensitive values from diagnostics, developers must ensure all diagnostic paths honor this scrubbing to prevent accidental leakage.

### In-Process Memory Exposure

Tokens are stored as plain Swift `String` instances in heap memory. A memory dump or debugger attached to the running app can read these values directly. CodexBar does not currently use the macOS Secure Enclave, Keychain services, or secure memory buffers for transient storage, leaving keys vulnerable to extraction via memory inspection tools.

### Provider Host Validation Risks

While tokens are only transmitted after host validation (implemented in [`ZaiProviderDescriptor.swift`](https://github.com/steipete/CodexBar/blob/main/ZaiProviderDescriptor.swift), lines 36-40), a compromised configuration could redirect a provider to an attacker-controlled endpoint. In this scenario, the API key would be leaked in the HTTP `Authorization` header despite the validation checks, as the token is sent after the connection is established.

### Accidental Version Control Exposure

Running `git add .` from the project root could stage configuration files containing keys. Although the repository includes a `.gitignore` entry for `*.json`, manually created files or override configs might bypass this protection, risking credential exposure in public repositories.

## Mitigation Strategies for Secure Token Management

To reduce the attack surface while using CodexBar, implement the following defensive measures:

- **Prefer environment variables** over config files for CI/CD or shared machines. The `SettingsReader` implementation already prioritizes environment variables; avoid persisting credentials to disk where possible.

- **Restrict file permissions** by running `chmod 600 ~/.codexbar/config.json` to limit read access to the file owner only.

- **Filter subprocess environments** before spawning child processes. Remove `*_API_KEY` entries that are not required, referencing the scrubbing map defined in `TokenAccountSupportCatalog+Data.swift`.

- **Validate provider URLs** rigorously. Keep the host-validation logic in provider descriptors updated and consider implementing DNS pinning to prevent redirection attacks.

- **Implement CI checks** that forbid committing files matching `*.json` containing `API_KEY` patterns to prevent accidental credential leakage.

## Secure Implementation Examples

The following Swift patterns demonstrate safer handling of credentials within the CodexBar ecosystem:

```swift
// Reading OpenAI key from environment with validation
let openAIKey = OpenAIAPISettingsReader.apiKey(environment: ProcessInfo.processInfo.environment)
guard let apiKey = openAIKey, !apiKey.isEmpty else {
    fatalError("OpenAI API key not set – export OPENAI_API_KEY or place it in ~/.codexbar/config.json")
}

// Spawning subprocess without leaking other provider keys
var safeEnv = ProcessInfo.processInfo.environment
safeEnv.removeValue(forKey: "ANOTHER_PROVIDER_API_KEY")
let task = Process()
task.environment = safeEnv
task.executableURL = URL(fileURLWithPath: "/usr/bin/curl")
task.arguments = ["-H", "Authorization: Bearer \(apiKey)", "https://api.openai.com/v1/models"]
try task.run()

```

## Summary

- CodexBar reads API keys from environment variables or unencrypted `~/.codexbar/config.json` files, storing them as plain-text strings in memory.
- **Plain-text storage** exposes keys to backup services and other user processes with filesystem access.
- **Environment inheritance** risks leaking keys to child processes and crash dumps unless explicitly scrubbed.
- **Memory exposure** allows debuggers to extract tokens since they are not stored in Secure Enclave or secure buffers.
- Mitigation requires preferring environment variables, restricting file permissions to `600`, filtering subprocess environments, and implementing CI checks to prevent accidental commits.

## Frequently Asked Questions

### Does CodexBar encrypt API keys stored in the config file?

No. According to the source code in [`CLIDiagnoseCommand.swift`](https://github.com/steipete/CodexBar/blob/main/CLIDiagnoseCommand.swift) (line 265), the `~/.codexbar/config.json` file is written and read as unencrypted plain text. The application does not currently implement encryption at rest for configuration files. You should mitigate this by restricting file permissions to `600` and preferring environment variables for sensitive credentials.

### How does CodexBar prevent API keys from appearing in logs?

The codebase includes specific scrubbing logic in `UsageStore+APIKeyDebug.swift` (line 19) and `TokenAccountSupportCatalog+Data.swift` that identifies environment variables matching `*_API_KEY` patterns and replaces their values with redacted placeholders in diagnostic output. However, this scrubbing must be manually applied to all logging paths to ensure complete coverage, as not all diagnostic commands automatically inherit the scrubbing map.

### Can API keys be extracted from CodexBar's memory while it is running?

Yes. CodexBar stores tokens as standard Swift `String` instances in process memory. Without using the macOS Secure Enclave or Keychain for transient storage, these values are vulnerable to memory dumps and debugger attachment. There is currently no functionality to zero out strings after use, though wrapping tokens in a custom type that overwrites its buffer on deinitialization could reduce exposure.

### What happens if a malicious provider URL is configured in CodexBar?

The `ProviderTokenResolver` validates hosts before sending tokens, as implemented in [`ZaiProviderDescriptor.swift`](https://github.com/steipete/CodexBar/blob/main/ZaiProviderDescriptor.swift) (lines 36-40). However, if an attacker compromises the configuration to point to an attacker-controlled endpoint, the API key will be transmitted in the HTTP `Authorization` header to that malicious server. Always validate provider URLs manually and use DNS pinning where possible to prevent this redirection attack.