How API Keys and Secrets Are Managed in Munder Difflin: A Security-First Approach

Munder Difflin uses a three-layer secret management system where API keys are stored in a write-only broker, injected via environment variables at runtime, and never written to disk or exposed in the UI after being set.

This security architecture ensures that AI provider credentials—including OpenAI, Anthropic, Google, and Groq keys—remain confidential while enabling seamless integration with multiple LLM backends. The design follows a "bring-your-own-keys" model that keeps secrets out of source control and in-memory only when needed.

Provider-Specific Environment Variable Mapping

The foundation of Munder Difflin's secret management is a clear mapping between AI providers and their expected environment variable names. This configuration lives in src/main/index.ts, where the PROVIDER_ENV object defines which variable each backend requires.

// src/main/index.ts – provider → env var map
export const PROVIDER_ENV = {
  anthropic: 'ANTHROPIC_API_KEY',
  openai:    'OPENAI_API_KEY',
  google:    'GEMINI_API_KEY',
  openrouter:'OPENROUTER_API_KEY',
  groq:      'GROQ_API_KEY',
};

This explicit mapping prevents key collisions and makes it trivial to add new providers without restructuring the secret handling logic.

The Write-Only Secret Broker

At the core of the system is a write-only secret broker that serves as the single source of truth for sensitive credentials. Users enter their keys through the Settings → AI Engines panel, but once saved, these values cannot be read back through the UI.

The broker stores secrets in a local JSON file within the application data directory. When an agent spawns, the system retrieves only the specific key needed for that provider—not the entire secret store.

// Settings UI – writing a secret (write-only broker)
await secretBroker.set('OPENAI_API_KEY', userProvidedKey);
// The broker stores the value locally but never exposes it again.

This write-only design eliminates an entire class of security vulnerabilities where malicious scripts or compromised UI components could exfiltrate credentials.

Runtime Environment Injection

When Munder Difflin launches a terminal agent (e.g., claude, codex, grok), it constructs a filtered environment that includes only the keys required for that specific provider. The buildPtyEnv utility in src/main/pty.ts handles this merge between process.env and the secret broker.

// src/main/pty.ts – merging secrets into child process environment
const env = {
  ...process.env,
  [PROVIDER_ENV[backend]]: key,   // e.g., process.env.OPENAI_API_KEY
};
spawnPty(command, args, { env });

The agent launch logic in src/main/hive.ts (lines 2775–2780) reads directly from process.env and passes these values to the spawned PTY. This ensures keys exist only in the memory space of processes that actively need them.

Development Safeguards

For local development, Munder Difflin provides a .env.example template with placeholder values. Critical protections prevent accidental secret exposure:

  • The .env.example file is never committed with real credentials
  • The CI pipeline explicitly blocks reading any actual .env file
  • The repository's SECURITY.md documents these constraints

This follows the principle that production secrets should never exist in developer working directories or version control history.

Key Implementation Files

File Purpose
src/main/index.ts Defines provider-to-environment-variable mapping (lines 392–396)
src/main/pty.ts Builds PTY environment with merged secrets (lines 652–660)
src/main/hive.ts Handles agent spawning with injected credentials (lines 2775–2780)
src/shared/ossModels.ts Catalogs which backends require which environment variables
.env.example Template for local development with placeholder values

Security Guarantees

The three-layer architecture provides concrete security properties:

  • No hard-coded secrets — All credentials originate from user input or environment injection
  • No repository leakage — Keys never appear in source control, logs, or crash dumps
  • Minimal attack surface — Secrets exist in memory only during active agent sessions
  • Provider isolation — Each spawned process receives only the specific credentials it requires

Summary

  • Environment variable mapping in src/main/index.ts standardizes how each AI provider expects its credentials
  • Write-only secret broker lets users configure keys without exposing them back through the UI
  • Runtime injection via buildPtyEnv in src/main/pty.ts places secrets only in child processes that need them
  • Development templates and CI protections prevent accidental credential commits
  • No persistence — Keys are never written to disk in recoverable form, only held in memory during active sessions

Frequently Asked Questions

Does Munder Difflin store API keys in the source code?

No. API keys are never hard-coded. The repository contains only a .env.example template with placeholder values. Real credentials are stored in a local, write-only JSON file managed by the secret broker and injected at runtime.

Can I retrieve an API key after entering it in the Settings UI?

No. The secret broker is write-only by design. Once you paste a key and save it, the UI cannot display it again. This prevents credential theft through XSS, compromised dependencies, or screen sharing accidents. You must re-enter keys if you need to change them.

What happens to API keys when I close Munder Difflin?

Keys persist in the local secret broker's encrypted store so they're available on restart, but they are never loaded into memory until an agent actually spawns. When the application closes, no API keys remain in active process memory.

How does Munder Difflin support multiple AI providers simultaneously?

The PROVIDER_ENV mapping associates each provider with a distinct environment variable. When spawning an agent for a specific backend, only that provider's key is injected into the child process environment. This isolation prevents one provider's credentials from leaking to another.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →