MCP Airlock
# MCP Airlock
[](https://github.com/lara-muhanna/mcp-airlock/actions/workflows/ci.yml)
[](./LICENSE)
[](./pyproject.toml)
**Zero-trust security gateway for MCP tools.**
MCP Airlock turns every tool call into a short-lived, context-bound capability decision with tamper-evident provenance.
## Why this exists
Agent tool ecosystems are failing at one painful boundary: **the jump from untrusted prompt text to privileged tool execution**.
Current patterns are usually one of:
- static allowlists (`agent can call tool X`)
- weak regex filtering
- post-hoc logs with no integrity guarantees
They fail when prompt injection mutates intent mid-session, causing silent privilege escalation or data exfiltration.
MCP Airlock solves this with a missing primitive for MCP:
- **Capability Leases**: short-lived, signed, context-bound rights (`session + intent + tool scope + constraints`)
- **Context-Aware Policy**: dynamic authorization on every call (risk score + tool constraints + lease checks)
- **Tamper-Evident Provenance**: append-only hash chain across all allow/deny decisions
## Core innovation
### Context-Bound Capability Leases (CBCL)
Each tool call is authorized against a signed lease:
- Bound to `session_id`
- Bound to `intent_hash`
- Scoped to specific tools
- Time-limited
- Optional constraints (e.g. allowed domains, max risk)
If a prompt injection tries to change intent or jump tool scope, execution is denied.
## Architecture
```mermaid
flowchart LR
A[Agent / MCP Client] -->|tools/call| B[MCP Airlock Server]
B --> C[Risk Engine]
B --> D[Capability Verifier]
B --> E[Policy Engine]
E -->|allow| F[Tool Adapter Layer]
E -->|deny| G[Policy Deny Response]
F --> H[External APIs / Internal Services]
B --> I[Provenance Ledger Hash Chain]
```
### Trust boundaries
```mermaid
flowchart TB
subgraph Untrusted
U1[Prompt Content]
U2[Agent Reasoning Trace]
end
subgraph Trusted Control Plane
T1[MCP Airlock]
T2[Policy + Lease Validation]
T3[Signed Provenance Ledger]
end
subgraph External Targets
X1[Public APIs]
X2[Internal APIs]
end
U1 --> T1
U2 --> T1
T1 --> T2
T2 --> X1
T2 --> X2
T1 --> T3
```
## Key features
- MCP stdio server compatible with `initialize`, `tools/list`, `tools/call`
- Capability issuance tool: `airlock_issue_capability`
- Agent/API usage analytics tool: `airlock_usage_stats`
- API exposure measurement tool: `airlock_exposure_report`
- Policy enforcement middleware with per-tool risk thresholds
- Prompt-injection signature scoring
- SSRF-resistant HTTP tool adapter (`http_get_json`)
- Real API integration example (`weather_hourly`)
- Tamper-evident provenance log + verification command
- Sandbox hardening guide for agentic API security
- CLI for serve/demo/issue/verify/stats/exposure
## 2-minute quickstart
```bash
git clone https://github.com/lara-muhanna/mcp-airlock
cd mcp-airlock
python -m pip install -e .
python -m mcp_airlock --config examples/airlock.config.json demo
```
What you will see:
- a human-friendly summary (handshake, capability, allow/deny, audit integrity)
- malicious call denied with plain-English reasons
- signed provenance evidence
## One-command local demo (no install)
```bash
python -m mcp_airlock --config examples/airlock.config.json demo --city Austin --state Texas
```
For full JSON payloads during demo:
```bash
python -m mcp_airlock --config examples/airlock.config.json demo --raw
```
## Run as MCP server
```bash
python -m mcp_airlock --config examples/airlock.config.json serve
```
MCP client setup examples:
- [`docs/CLIENT_SETUP.md`](./docs/CLIENT_SETUP.md)
- [`docs/SANDBOXING_AGENTIC_APIS.md`](./docs/SANDBOXING_AGENTIC_APIS.md)
- [`examples/client-configs/claude_desktop.mcp.json`](./examples/client-configs/claude_desktop.mcp.json)
- [`examples/client-configs/cursor.mcp.json`](./examples/client-configs/cursor.mcp.json)
## CLI
```bash
# Issue a capability directly
python -m mcp_airlock --config examples/airlock.config.json issue \
--session-id sess-123 \
--subject agent:planner \
--tools weather_hourly,http_get_json \
--intent "Plan safe outdoor activities" \
--ttl-seconds 900 \
--constraints '{"allowed_domains":["api.open-meteo.com"],"max_risk":0.6}'
# Verify audit integrity
python -m mcp_airlock --config examples/airlock.config.json verify-log
# API usage stats by agent
python -m mcp_airlock --config examples/airlock.config.json stats --lookback-hours 24
# API exposure measurement
python -m mcp_airlock --config examples/airlock.config.json exposure --lookback-hours 24
```
## Example agent integration
Run:
```bash
python examples/agent_integration.py
```
This script:
- starts Airlock over stdio
- negotiates MCP initialize/list
- issues a lease
- runs a normal tool call
- runs an injected call that gets blocked
## Config template
`examples/airlock.config.json`
```json
{
"secret_key": "dev-secret-change-this-before-production",
"provenance_log": "./airlock-provenance.log",
"max_ttl_seconds": 1800,
"default_risk_threshold": 0.55,
"tools": {
"weather_hourly": {
"require_capability": true,
"risk_threshold": 0.7
},
"http_get_json": {
"require_capability": true,
"risk_threshold": 0.45,
"allowed_domains": ["api.open-meteo.com", "geocoding-api.open-meteo.com"]
}
}
}
```
## Security model summary
1. Agent requests lease via `airlock_issue_capability`.
2. Lease is HMAC-signed and includes `session`, `intent_hash`, `tool_scope`, `expiry`.
3. Every `tools/call` request includes `_capability` and `_context`.
4. Airlock enforces:
- lease validity + signature
- session and intent continuity
- risk threshold
- tool-specific constraints (e.g., domain allowlist)
5. Decision + evidence is hash-chained to provenance log.
## Project structure
```
mcp-airlock/
mcp_airlock/
cli.py
server.py
policy.py
capability.py
risk.py
provenance.py
config.py
tool_ids.py
tools/
http_json.py
weather.py
examples/
airlock.config.json
agent_integration.py
docs/
CLIENT_SETUP.md
SANDBOXING_AGENTIC_APIS.md
```
## Roadmap
- Upstream MCP proxy mode (wrap existing MCP servers transparently)
- OPA/Rego policy backend
- OpenTelemetry traces + SIEM sinks
- Managed capability broker + key rotation
- Signed replay package for incident response
## Community
- Contribution guide: [`CONTRIBUTING.md`](./CONTRIBUTING.md)
- Security policy: [`SECURITY.md`](./SECURITY.md)
- Code of conduct: [`CODE_OF_CONDUCT.md`](./CODE_OF_CONDUCT.md)
- Release checklist: [`docs/RELEASE_CHECKLIST.md`](./docs/RELEASE_CHECKLIST.md)
## License
MIT
TDQS
Scored across 4 tools
Each tool targets a distinct function (provenance auditing, capability issuance, generic HTTP fetching, and weather retrieval) with minimal overlap. An agent can easily distinguish when to use each based on the task requirements.
Mixed naming patterns: two tools use 'airlock_' prefix with verbs (issue, audit_tail), while others use 'http_' prefix or no prefix (weather_hourly). The weather tool breaks the verb-first convention used by others, using a noun-adjective pattern instead.
Four tools is acceptably compact but the set suffers from scope confusion, mixing core Airlock security functions with unrelated utility tools (weather, HTTP). This feels like two different servers merged together rather than a cohesive toolset.
The Airlock domain (capability management) is severely underdeveloped, offering only issuance and audit tail reading without revocation, validation, or capability listing. The utility tools (weather, HTTP) are also minimal, offering only hourly forecasts and GET requests without parameter customization.