How the Archon Env-Leak Scanner Detects Sensitive Variables in .env Files

The Archon env-leak scanner is a pure-function utility in packages/core/src/utils/env-leak-scanner.ts that iterates over auto-loaded dotenv files, parses key-value pairs, and flags any variables matching a predefined set of sensitive keys like OPENAI_API_KEY and ANTHROPIC_API_KEY.

Archon is an open-source AI coding assistant that prevents accidental credential exposure by scanning environment files before project registration. The env-leak scanner specifically targets standard Node.js dotenv auto-load patterns to ensure API keys and authentication tokens never leak into managed configurations.

What Defines a "Sensitive" Key

According to the Archon source code, sensitivity is determined by exact string matching against a hardcoded Set defined at the top of env-leak-scanner.ts (lines 4‑12):

export const SENSITIVE_KEYS = new Set([
  'ANTHROPIC_API_KEY',
  'ANTHROPIC_AUTH_TOKEN',
  'CLAUDE_API_KEY',
  'CLAUDE_CODE_OAUTH_TOKEN',
  'OPENAI_API_KEY',
  'CODEX_API_KEY',
  'GEMINI_API_KEY',
]);

Any environment variable key that exactly matches one of these seven strings triggers a leak finding. The use of a Set structure ensures O(1) lookup time during the scan.

Which Files the Scanner Inspects

Archon does not scan arbitrary files. It strictly examines the filenames that Node.js automatically loads as environment configuration, as defined in env-leak-scanner.ts (lines 14‑21):

export const AUTOLOADED_FILES = [
  '.env',
  '.env.local',
  '.env.development',
  '.env.production',
  '.env.development.local',
  '.env.production.local',
];

The scanner iterates over this array in order, constructing absolute paths relative to the target directory passed to the scan function.

The Scanning Algorithm

The core logic resides in scanPathForSensitiveKeys(dirPath), exported from env-leak-scanner.ts (lines 59‑91). This function returns a LeakReport object containing any detected exposures.

Step-by-Step Execution

  1. Path Resolution: For each filename in AUTOLOADED_FILES, the scanner joins it with the provided dirPath using join().

  2. Existence Check: Uses existsSync(fullPath) to skip missing files silently.

  3. File Reading: Reads the file via readFileSync(fullPath, 'utf8'). If reading fails (permissions, encoding issues), the scanner captures the error code and records the file as [unreadable — ${code}] in the findings.

  4. Line Parsing: Splits the file contents by newline and processes each line:

    • Trims whitespace
    • Ignores lines starting with # (comments)
    • Ignores lines without an = character
    • Extracts the substring before the first = as the key name
  5. Key Matching: Checks if the extracted key exists in SENSITIVE_KEYS using .has().

  6. Report Generation: Accumulates matches into a LeakFinding array. If at least one sensitive key is found, the file is added to the findings property of the returned LeakReport.

The LeakReport interface (lines 28‑31) structures the results:

export interface LeakReport {
  path: string;
  findings: LeakFinding[];
}

Error Handling and User Context

When scanPathForSensitiveKeys() returns findings, Archon throws an EnvLeakError that formats context-specific messages based on the call site—whether the scan originated from the UI registration flow, CLI auto-register, or a pre-spawn check. This ensures users see relevant instructions for their specific interface when a leak is detected.

The error formatting logic resides in the same file immediately after the scanner implementation, handling edge cases like unreadable files by preserving the Node.js error code in the report output.

Implementation Examples

Scanning a Project Directory Directly

import { scanPathForSensitiveKeys } from '@archon/core/src/utils/env-leak-scanner';

const report = scanPathForSensitiveKeys(process.cwd());

if (report.findings.length === 0) {
  console.log('✅ No sensitive keys found in .env files.');
} else {
  console.error('⚠️  Sensitive environment variables detected:');
  for (const f of report.findings) {
    console.error(`  • ${f.file}: ${f.keys.join(', ')}`);
  }
}

Example output when leaks are found:


⚠️  Sensitive environment variables detected:
  • .env: OPENAI_API_KEY, CLAUDE_API_KEY

Integrating with Registration Flows

Before persisting a new codebase, registration commands call the scanner and throw EnvLeakError if violations exist:

import { EnvLeakError, scanPathForSensitiveKeys } from '@archon/core/src/utils/env-leak-scanner';
import { registerCodebase } from '@archon/core/src/commands/register';

async function registerWithLeakCheck(path: string) {
  const report = scanPathForSensitiveKeys(path);
  if (report.findings.length) {
    throw new EnvLeakError(report, 'register-cli');
  }
  await registerCodebase(path);
}

Higher-level UI and CLI handlers catch this error to present consent prompts or blocking dialogs based on the context parameter passed to the constructor.

Summary

  • Hardcoded Sensitivity: Archon uses a Set named SENSITIVE_KEYS in env-leak-scanner.ts to define exactly seven sensitive variable names, including OPENAI_API_KEY and ANTHROPIC_API_KEY.
  • Strict File targeting: Only the six standard Node.js dotenv filenames listed in AUTOLOADED_FILES are inspected.
  • Synchronous Parsing: The scanner uses readFileSync and manual line splitting to extract keys left of the = character, skipping comments and malformed lines.
  • Structured Reporting: Results return via a LeakReport interface containing LeakFinding objects with filename and key arrays.
  • Contextual Errors: When leaks are detected, EnvLeakError provides interface-specific messaging for UI, CLI, or pre-spawn contexts.

Frequently Asked Questions

What specific API keys does Archon consider sensitive?

Archon flags seven specific environment variables: ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, CLAUDE_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, OPENAI_API_KEY, CODEX_API_KEY, and GEMINI_API_KEY. These are hardcoded in the SENSITIVE_KEYS Set inside packages/core/src/utils/env-leak-scanner.ts.

How does Archon handle unreadable .env files?

If readFileSync throws an error due to permissions or encoding issues, the scanner catches the exception, extracts the Node.js error code, and records a finding with the key listed as [unreadable — ${code}]. This ensures users are alerted to potential secrets even when file contents cannot be parsed.

Can I customize which variables the env-leak scanner flags?

Currently, the scanner does not support runtime configuration of sensitive keys. The SENSITIVE_KEYS Set is exported as a constant and would require modification of the source code in packages/core/src/utils/env-leak-scanner.ts to add or remove variables from the detection list.

When does the env-leak scan actually execute?

Archon triggers the scan during codebase registration flows—whether initiated through the web UI, CLI commands, or automated setup processes. The scan runs before any persistence occurs, throwing EnvLeakError if sensitive variables are detected, thereby blocking registration until the issue is resolved.

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 →