Skip to main content
Glama

🛡️ code-airlock

PyPI version License: MIT Benchmark Runtime

Zero-trust PII & secret airlock for AI coding agents (Claude Code, OpenCode, Cursor, Windsurf, Cline).

code-airlock sits between your local codebase and LLM agents as both a FastMCP Server and an OpenAI-compatible SSE Proxy. It replaces live API keys, database passwords, and PII with reversible, session-consistent placeholders (<API_KEY_1>, <AUTH_TOKEN_1>, <PERSON_1>) before text enters LLM context—and restores them byte-exact on disk or inside child test processes without the AI ever seeing the raw values.

  • Lightweight & Universal (~60 MB): Powered by a two-stage deterministic Regex + Pure ONNX Runtime (gliner_small-v2.1) cascade. No torch bloat, no GPU required, and 100% offline after initial model warmup.

  • Sub-Millisecond Stage 1 (0.20 ms p50): Instant secret detection and Git pre-commit scanning.

  • Safe Subprocess Execution (airlock_exec): Run pytest or scripts against live .env credentials while automatically scrubbing secrets from stdout and stderr before logs return to the agent.


⚡ Quickstart (Add to Your Agent Harness in 10 Seconds)

🤖 One-Prompt Agent Install (OpenCode / Claude Code / Cursor)

Tell your coding agent:

Install https://github.com/sarthexe/code-airlock

Or run:

pip install -U code-airlock && python -m code_airlock install

code-airlock configures OpenCode, Claude Code, and Cursor globally in one shot — no repo clutter. It merges its MCP server into each harness's home config without overwriting existing servers, appends the airlock rules to the global OpenCode and Claude instruction files, warms up the ONNX model, and installs the Git pre-commit hook when run inside a repository. The same rules also travel in the MCP handshake, so every new project gets them automatically.

Limit it with --target opencode|claude|cursor. Use python -m code_airlock init inside a project for a local AGENTS.md, CLAUDE.md, or .cursorrules. Restart your agents afterward to load the seven airlock_* tools.

You can run code-airlock directly via uvx (zero install, no virtual environment needed) or install it globally via pip.

Option A: Zero-Install via uvx (Recommended)

1. Claude Code

claude mcp add code-airlock -- uvx code-airlock

2. OpenCode (~/.config/opencode/opencode.json)

{
  "mcp": {
    "servers": {
      "code-airlock": {
        "type": "local",
        "command": ["uvx", "code-airlock"]
      }
    }
  }
}

3. Cursor / Claude Desktop / Windsurf (.cursor/mcp.json)

{
  "mcpServers": {
    "code-airlock": {
      "command": "uvx",
      "args": ["code-airlock"]
    }
  }
}

Warm up the ONNX model & initialize your repository with uvx:

# 1. Pre-cache ONNX weights & run a 1-second round-trip self-test
uvx --from code-airlock python -m code_airlock doctor

# 2. Add the local rule file for your harness plus .airlock.toml and Git pre-commit hook
uvx --from code-airlock python -m code_airlock init --pre-commit --config

Option B: Standard pip install

pip install code-airlock

# Verify installation & warm up local ONNX model cache
python -m code_airlock doctor

# Initialize project guardrails & Git pre-commit secret shield
python -m code_airlock init --pre-commit --config

Claude Code:

claude mcp add code-airlock -- python -m code_airlock.mcp_server

OpenCode (~/.config/opencode/opencode.json):

{
  "mcp": {
    "servers": {
      "code-airlock": {
        "type": "local",
        "command": ["python", "-m", "code_airlock.mcp_server"]
      }
    }
  }
}

Cursor / Claude Desktop (.cursor/mcp.json):

{
  "mcpServers": {
    "code-airlock": {
      "command": "python",
      "args": ["-m", "code_airlock.mcp_server"]
    }
  }
}

Related MCP server: zentric-protocol-mcp

🛠️ How It Works in Your Daily Workflow

Once added to your harness and initialized via init --pre-commit, your coding agent automatically uses code-airlock for sensitive operations:

  1. Reading & Refactoring Configs Safely (airlock_read_file & airlock_write_file):

    • You ask: "Read .env and generate a production docker-compose.yml."

    • The agent calls airlock_read_file(".env") and sees only:

      STRIPE_SECRET_KEY=<API_KEY_1>
      DATABASE_URL=postgres://admin:<AUTH_TOKEN_1>@10.0.4.12:5432/prod
    • The agent writes the new file using <API_KEY_1> and <AUTH_TOKEN_1> via airlock_write_file(). code-airlock rehydrates the real secrets onto disk behind the scenes.

  2. Running Tests Without Leaking stdout (airlock_exec):

    • You ask: "Run pytest using .env to verify the Stripe webhook."

    • The agent calls airlock_exec(command=["pytest", "-v"], env_file=".env").

    • code-airlock injects the real credentials into the child process memory, executes the test, and scrubs any secret values printed in stdout or stderr back into <API_KEY_1> before returning the output to the LLM.

  3. Blocking Accidental Git Commits (scan --staged):

    • Whenever you or the agent runs git commit, the pre-commit hook runs python -m code_airlock scan --staged in 0.20 ms, blocking any staged file that contains a live credential.


💡 Real-World Use Cases

1. Refactoring a Monolith Without Leaking Database Credentials

The scenario: You ask your AI coding agent: "Read our legacy settings.py and extract the database connection strings into our new PostgreSQL microservice config."

The risk: Raw database URLs containing a root password (for example, postgres://admin:<raw-password>@prod-db.internal:5432/main) get uploaded to the LLM's cloud logs.

How code-airlock stops it:

  1. The agent calls airlock_read_file("settings.py").

  2. code-airlock intercepts the read and replaces the URI password with <AUTH_TOKEN_1>.

  3. The agent refactors the codebase using <AUTH_TOKEN_1>.

  4. When saving the new microservice config, airlock_write_file() restores the real database password byte-exact on disk. The LLM never saw the raw credential.

2. Running Integration Tests via an AI Agent Without stdout Leaks

The scenario: You ask your agent: "Write a Stripe webhook integration test and run pytest to make sure it passes."

The risk: Your pytest runner or test setup script crashes, outputting a full stack trace that prints the live STRIPE_SECRET_KEY value directly into the terminal—which the agent captures and streams back to its context window.

How code-airlock stops it:

  1. The agent calls airlock_exec(command=["pytest", "tests/test_stripe.py"], env_file=".env").

  2. code-airlock injects the real .env secrets into the child process memory so the test executes successfully.

  3. If pytest prints an error stack trace or environment dump containing the live Stripe key, airlock_exec automatically scrubs stdout and stderr, masking it back into <API_KEY_1> before returning the logs to the agent.

3. Zero-Config Git Pre-Commit Guardrails for Team Repos

The scenario: A junior developer (or an overzealous AI agent) writes a new feature, hardcodes an AWS AKIA... key or OpenAI sk-proj-... token into a test file, and types git commit -m "add test helper".

The risk: The secret gets committed to git history, forcing you to rotate keys and rewrite git logs.

How code-airlock stops it:

  1. Running python -m code_airlock init --pre-commit drops a lightweight hook into .git/hooks/pre-commit.

  2. Whenever git commit runs, the hook executes code-airlock scan --staged in 0.20 ms.

  3. If a secret is detected, it blocks the commit instantly and prints a masked preview (file.py:12 -> [API_KEY] sk***45), keeping your repository clean.

4. Managing Company-Specific Internal Tokens via .airlock.toml

The scenario: Your engineering team uses custom internal formats (like employee IDs EMP-84920 or internal JIRA ticket keys JIRA-4012) that standard PII scanners might ignore or falsely flag as general text.

The risk: Internal tickets or proprietary identifiers leak into third-party LLM logs.

How code-airlock stops it:

Add an .airlock.toml file in the repository root:

[custom_patterns]
EMPLOYEE_ID = 'EMP-[0-9]{5}'
INTERNAL_TICKET = 'JIRA-[0-9]{3,5}'

Stage 1 evaluates these custom rules locally in sub-milliseconds, converting them to <EMPLOYEE_ID_1> and <INTERNAL_TICKET_1> tokens in memory before any text reaches the LLM.

All detection happens locally. The upstream model sees only tokens, and the vault restores the real values on your machine.


🧰 Complete MCP Toolkit (7 Tools)

MCP Tool

Description

airlock_read_file(path)

Reads a file, dehydrates all secrets/PII into <ENTITY_N> tokens in the session vault, and returns sanitized text to the agent.

airlock_write_file(path, content)

Rehydrates <ENTITY_N> placeholders (case- and whitespace-tolerant), verifies no hallucinated tokens remain, and writes real values to disk.

airlock_exec(command, env_file="")

Runs a subprocess (shell=False) with real .env secrets injected into child memory and scrubs stdout/stderr before returning to the LLM.

airlock_scrub_text(text, use_ner=False)

Scrubs in-memory strings, logs, or code snippets directly and registers tokens in the active vault.

airlock_dehydrate(text)

Converts raw text into sanitized text with <ENTITY_N> tokens.

airlock_rehydrate(text)

Restores <ENTITY_N> tokens in a string back to their original values.

airlock_vault_status()

Returns active token count and categories (API_KEY, AUTH_TOKEN, etc.) without ever exposing raw values.

Built-In Security Guardrails

  • Workspace & System Folder Jailing: Blocks path traversal and sensitive directories (.ssh, .aws, .gnupg, .kube, /etc, System32). Set AIRLOCK_WORKSPACE=/path/to/repo to strictly jail file operations to a single directory.

  • Hallucination-Safe Write Gate: If an LLM invents a non-existent token (e.g., <API_KEY_999>), airlock_write_file refuses to write a broken file and returns an unresolved_tokens error so the agent can self-correct.

  • Forgiving Rehydration: Automatically resolves LLM casing or spacing variations (<api_key_1> or < API_KEY_1 >).

  • Crash-Safe Memory Hygiene: VaultSession.__repr__ and __str__ never expose raw secrets in stack traces or crash logs.

  • Binary & Size Caps: Rejects non-UTF-8 binary files (\x00) and files over 1 MB.


💻 CLI Reference

python -m code_airlock                 # Start FastMCP stdio server (default)
python -m code_airlock install         # Configure all harnesses globally, warm up model
python -m code_airlock doctor          # Warm up ONNX model, run self-test & print IDE configs
python -m code_airlock init            # Write the local rule file for the detected harness
python -m code_airlock init --pre-commit --config  # Also install Git hook + starter .airlock.toml
python -m code_airlock scan src/       # Fast Stage-1 secret scan across paths (0.20ms/file)
python -m code_airlock scan --staged   # Scan staged Git changes (exits 1 on findings, masks preview)
python -m code_airlock scan --deep .   # Deep scan with Stage 1 + Stage 2 ONNX NER
python -m code_airlock proxy           # Launch OpenAI-compatible SSE proxy on :8000

⚙️ Project Configuration (.airlock.toml)

Drop an .airlock.toml file in your project root (or generate one via python -m code_airlock init --config) to define custom Stage 1 regex rules and Stage 2 allowlists for your team:

[allowlist]
terms = ["MyInternalApp", "staging.corp.local"]

[custom_patterns]
EMPLOYEE_ID = 'EMP-[0-9]{6}'
INTERNAL_TICKET = 'JIRA-[0-9]{4,6}'
  • [custom_patterns]: Evaluated in Stage 1 (~0.20 ms) and mapped to reversible tokens (<EMPLOYEE_ID_1>, <INTERNAL_TICKET_1>).

  • [allowlist]: Prevents domain-specific terms or internal hostnames from being flagged by Stage 2 NER.


🌐 OpenAI-Compatible SSE Proxy Mode

Need network-level protection for any OpenAI SDK client or custom agent pipeline? Run the streaming HTTP proxy:

code-airlock-proxy
# Or: python -m code_airlock proxy

Point your client's OPENAI_BASE_URL to http://localhost:8000/v1 and set UPSTREAM_BASE_URL (defaults to https://api.openai.com).

  • Outbound: Scrubs all messages in POST /v1/chat/completions before forwarding upstream.

  • Inbound Streaming (StreamRehydrator): Buffers only inside open <...> brackets across arbitrary network chunks (even 1-byte SSE splits) and restores secrets on the fly with zero latency on regular text.


📊 Benchmarks (sarthexe/pii-airlock-bench)

Evaluated on the open 4-split benchmark dataset (sarthexe/pii-airlock-bench) covering 2,000 rows, 5,817 entity spans, 250 hard negatives (UUIDs, Git SHAs, dummy placeholders, localhost IPs, CLI flags), and 1/2/7-byte adversarial SSE stream splits:

Suite

Rows

Recall / Precision / F1

Token Accuracy

Hard Negatives (0-FP)

Clean Rows (0-FP)

SSE 1/2/7-Byte Round-Trip

dev_prompts

1,000

100.0% / 100.0% / 100.0%

100.0%

0 / 0

200 / 200

1,000 / 1,000

git_leaks

500

100.0% / 100.0% / 100.0%

100.0%

250 / 250

100 / 100

500 / 500

mcp_configs

250

100.0% / 100.0% / 100.0%

100.0%

0 / 0

50 / 50

250 / 250

adversarial_sse

250

100.0% / 100.0% / 100.0%

100.0%

0 / 0

0 / 0

250 / 250

Total (all)

2,000

100.0% / 100.0% / 100.0%

100.0%

250 / 250

350 / 350

2,000 / 2,000

  • Stage 1 Latency (Regex + URI/Key-Value Heuristics): 0.203 ms p50

  • Stage 2 Latency (Pure ONNX CPU gliner_small-v2.1): 55.20 ms p50 (CUDAExecutionProvider automatically used when onnxruntime-gpu is present)

Reproduce locally:

python benchmarks/benchmark.py --suite all

📄 License

MIT © Sarthak Kumar Maurya

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      Security middleware for LLM apps and AI agent pipelines. Detects prompt injection attacks (22 signatures, 7 languages) and anonymizes PII (17 entity types). Deterministic, sub-25ms, GDPR Art.30 compliant.
      -
    • A
      license
      Not graded
      quality
      C
      maintenance
      Local CLI and MCP server that redacts secrets from logs, files, and diffs before sending them to AI agents, with stable placeholders and token-budgeted truncation.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI agents to scan and audit environment files for leaked secrets, sanitize them, encrypt/decrypt vaults, and run processes with zero-disk secret injection.
      MIT