Skip to main content

Enterprise LLM proxy built on LiteLLM — logging, guardrails, and unified access for AI coding tools.

Project description

Airlock

Enterprise LLM proxy built on LiteLLM — unified access, logging, and guardrails for AI coding tools.

Airlock sits between your developers and LLM providers, giving you visibility and control without slowing anyone down.

  ┌──────────┐   ┌──────────┐   ┌──────────┐
  │  Cursor   │   │  Claude  │   │  Copilot  │
  │           │   │   Code   │   │           │
  └─────┬─────┘   └─────┬────┘   └─────┬─────┘
        │               │              │
        └───────────┬───┘──────────────┘
                    │
              ┌─────▼──────┐
              │   AIRLOCK   │  ← logging, PII guard, keyword guard
              │  (LiteLLM)  │
              └──────┬──────┘
                     │
           ┌─────────┼──────────┐
           │         │          │
      ┌────▼───┐ ┌───▼────┐ ┌──▼──────┐
      │Anthropic│ │ OpenAI │ │ Internal│
      │  API    │ │  API   │ │  RAG    │
      └────────┘ └────────┘ └─────────┘

What it does

Concern How Airlock handles it
Unified access Single OpenAI-compatible endpoint for all providers
Logging Every request/response logged as structured JSONL
PII stripping Microsoft Presidio scrubs credit cards, SSNs, emails, etc. before they leave the network
Keyword blocking Custom blocklist prevents restricted project names or terms from leaking
Budget control Per-user/per-team spend limits via LiteLLM virtual keys
Multi-tool support Works with Cursor, Claude Code, GitHub Copilot, and any OpenAI-compatible client
Self-hosted models Route to local vLLM, Ollama, or any OpenAI-compatible endpoint alongside cloud providers
Interactive testing Built-in Basic Chat screen to test LLM connectivity and inspect full request/response cycles
AI advisor Ask an LLM about operational data — diagnose errors, tune guardrails, get config recommendations (local models preferred)

Getting started

Install from PyPI

pip install airlock-llm
python -m spacy download en_core_web_lg   # required for PII redaction
airlock init

airlock init generates config.yaml, .env, and a logs/ directory in the current working directory.

Install from source (quick setup)

git clone https://github.com/coreyt/airlock && cd airlock
./scripts/setup.sh

This installs Airlock and its dependencies, downloads the spaCy model for PII redaction, and runs airlock init. Pass --pip to use pip instead of uv.

Developer setup

git clone https://github.com/coreyt/airlock && cd airlock
./scripts/setup-dev.sh

Everything in the standard setup, plus all optional extras (test, metrics, tracing, search, s3, sql), install verification, and a test suite run. Pass --pip to use pip instead of uv.

Add your API keys

Edit the generated .env file and fill in your provider keys:

# .env
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...

You only need keys for the providers you plan to use. If you only use Anthropic models, you can leave OPENAI_API_KEY blank.

Start the proxy

# Option A: TUI dashboard with built-in proxy (recommended)
uv run airlock tui --start

# Option B: proxy only (headless)
uv run airlock start

Airlock listens on http://localhost:4000 by default. Change the port with AIRLOCK_PORT in .env.

Test it

curl http://localhost:4000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-airlock-change-me" \
  -d '{
    "model": "claude-sonnet",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Or use the TUI's Basic Chat screen (press 5) to interactively test any configured model and inspect the full request/response headers and body.

Advisor

Ask an LLM about Airlock's operational data — diagnose errors, tune guardrails, understand trends:

# One-shot question
airlock advise "why does claude-sonnet have a high error rate?"

# Interactive session
airlock advise --interactive

# Force local model only (no data sent externally)
airlock advise --local-only "what should I tune?"

Or press 6 in the TUI for the Advisor screen. The advisor prefers local models (vLLM, Ollama) to avoid sending operational data to remote providers.

Alternative: Docker

docker compose up --build

Connecting AI tools

Point any OpenAI-compatible client at http://localhost:4000 (or your deployed Airlock URL).

Claude Code

# Install client-side hooks and route traffic through the proxy
airlock hooks install
eval $(airlock dogfood)
claude

Every request now flows through PII redaction, keyword blocking, and JSONL logging. Open airlock tui in another terminal to watch traffic in real time.

See dev/dogfooding.md for the full setup guide.

Cursor / Windsurf

In settings, set:

  • OpenAI Base URL: http://localhost:4000/v1
  • API Key: your Airlock master key (from .env)

GitHub Copilot

In VS Code settings.json:

{
  "github.copilot.advanced": {
    "debug.overrideProxyUrl": "http://localhost:4000/v1"
  }
}

Configuration

config.yaml

The main configuration file defines models, callbacks, and guardrails. See the inline comments in config.yaml for details.

Key sections:

  • model_list — which LLM providers/models to expose
  • litellm_settings — callbacks, timeouts, budgets
  • router_settings — routing strategy, fallbacks, provider budgets
  • guardrails — PII and keyword guards
  • mcp_servers — MCP tool servers (Armada, ADO, etc.) accessible via the proxy
  • general_settings — master key, host/port

Self-hosted / local models

Airlock supports any OpenAI-compatible endpoint (vLLM, Ollama, LocalAI, etc.) using the openai/ prefix with a custom api_base:

# config.yaml — add to model_list
- model_name: gemma-4
  litellm_params:
    model: openai/gemma4-31b          # model ID as reported by the server
    api_base: http://your-host:8000/v1
    api_key: os.environ/VLLM_API_KEY  # use "dummy-key" if server has no auth
# .env
VLLM_API_KEY=dummy-key

The model will appear in the TUI Basic Chat screen for interactive testing and can be used by any connected client via model: "gemma-4".

Environment variables

Variable Description Default
ANTHROPIC_API_KEY Anthropic API key
OPENAI_API_KEY OpenAI API key
AIRLOCK_MASTER_KEY Master key for admin endpoints
AIRLOCK_HOST Bind address (set to 0.0.0.0 to expose externally) 127.0.0.1
AIRLOCK_PORT Listen port 4000
AIRLOCK_LOG_DIR Directory for JSONL log files ./logs
AIRLOCK_MAX_LOG_DAYS Days to retain log files before cleanup 30
AIRLOCK_MAX_LOG_SIZE_MB Max log file size before rotation 500
AIRLOCK_BLOCKED_KEYWORDS Comma-separated restricted phrases
AIRLOCK_PII_ENTITIES Presidio entity types to redact CREDIT_CARD,US_SSN,EMAIL_ADDRESS,PHONE_NUMBER

Adding MCP servers

Airlock can proxy MCP tool servers alongside LLM providers. Add entries to mcp_servers in config.yaml. LiteLLM spawns stdio servers from the proxy's working directory, so command resolution matters.

Command resolution patterns

Module via python -m — cwd-independent, requires package installed in the proxy's venv:

mcp_servers:
  ado_mcp:
    command: uv
    args: ["run", "python", "-m", "ado_mcp.mcp.server"]
    env:
      ADO_ORG_URL: os.environ/ADO_ORG_URL
      ADO_PAT: os.environ/ADO_PAT

Installed script via uv run — cwd-independent, resolves from PATH/venv:

  armada:
    command: uv
    args: ["run", "armada-mcp"]
    env:
      ARMADA_PROFILE: essential

Script file — must use an absolute path (relative paths resolve against the proxy's cwd, not the server's project directory):

  mono_tui:
    command: python3
    args: ["/home/user/projects/my-mcp-server/server.py"]

Other runtimes:

  # Node.js
  my_node_server:
    command: node
    args: ["/path/to/server.js"]

  # npx (installed package)
  my_npx_server:
    command: npx
    args: ["my-mcp-server"]

  # Bun
  my_bun_server:
    command: bun
    args: ["run", "/path/to/server.ts"]

  # Poetry
  my_poetry_server:
    command: poetry
    args: ["run", "python", "-m", "my_server"]

Environment variables

Use os.environ/VAR_NAME to pass environment variables from Airlock's .env to the MCP server. Airlock validates these references at startup and gives clear error messages for missing values.

Guardrail coverage

All MCP tool calls flow through the same guardrail pipeline as LLM requests (PII redaction, keyword blocking, threat detection). MCP-specific guards add tool allowlist/blocklist and argument sanitization. No extra configuration needed — guardrails apply automatically.

Project structure

airlock/
├── proxy.py              # Entry point — launches LiteLLM subprocess
├── callbacks/            # JSONL logger, S3, SQL, Prometheus, OpenTelemetry
├── guardrails/           # PII redaction, keyword blocking, semantic, adaptive
├── fast/                 # Real-time: threat detection, circuit breaker, priority
├── slow/                 # Offline: log analysis, trend detection, tuning
├── hooks/                # Claude Code client-side hooks (session, prompt, audit)
├── advisor/              # LLM-powered operational advisor (agent loop, tools, proposals)
├── cli/                  # Unified CLI: init, start, status, tui, analyze, advise, hooks
└── tui/                  # Textual terminal dashboard (6 screens, proxy control)
scripts/
├── setup.sh              # Standard setup (install + init + spaCy model)
└── setup-dev.sh          # Developer setup (all extras + tests)

Production deployment

See docs/operations.md for deployment guides (Docker, Kubernetes, bare metal), monitoring, security checklist, and upgrade procedures.

See docs/troubleshooting.md for common issues and debugging.

License

Apache 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

airlock_llm-0.2.0.tar.gz (271.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

airlock_llm-0.2.0-py3-none-any.whl (195.6 kB view details)

Uploaded Python 3

File details

Details for the file airlock_llm-0.2.0.tar.gz.

File metadata

  • Download URL: airlock_llm-0.2.0.tar.gz
  • Upload date:
  • Size: 271.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for airlock_llm-0.2.0.tar.gz
Algorithm Hash digest
SHA256 126f8245c37968628d2d1c75b2d4d45f786bcf2137a415fef8aa1c34d3e122f7
MD5 3f7ed052bb1d51400beb5b7013d7ce30
BLAKE2b-256 905e06cf08daf54a95270cf453509f6a378d80ed0e87fb484da6bfadc472ea2c

See more details on using hashes here.

Provenance

The following attestation bundles were made for airlock_llm-0.2.0.tar.gz:

Publisher: release.yml on coreyt/airlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file airlock_llm-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: airlock_llm-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 195.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for airlock_llm-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 448c020c68bbaa13ba193ae23481ecb9c1e8617fa05146d719eba1b736d6d23d
MD5 8887c7265fab165a2f4a988e97f0d5be
BLAKE2b-256 1d1d19f531e3068019b74ae9bd80eb321d96c10db93d42b3ec3b89106b34dec1

See more details on using hashes here.

Provenance

The following attestation bundles were made for airlock_llm-0.2.0-py3-none-any.whl:

Publisher: release.yml on coreyt/airlock

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page