MCP Airlock
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
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
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
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)
python -m mcp_airlock --config examples/airlock.config.json demo --city Austin --state Texas
For full JSON payloads during demo:
python -m mcp_airlock --config examples/airlock.config.json demo --raw
Run as MCP server
python -m mcp_airlock --config examples/airlock.config.json serve
MCP client setup examples:
docs/CLIENT_SETUP.mddocs/SANDBOXING_AGENTIC_APIS.mdexamples/client-configs/claude_desktop.mcp.jsonexamples/client-configs/cursor.mcp.json
CLI
# 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:
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
{
"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
- Agent requests lease via
airlock_issue_capability. - Lease is HMAC-signed and includes
session,intent_hash,tool_scope,expiry. - Every
tools/callrequest includes_capabilityand_context. - Airlock enforces:
- lease validity + signature
- session and intent continuity
- risk threshold
- tool-specific constraints (e.g., domain allowlist)
- 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 - Security policy:
SECURITY.md - Code of conduct:
CODE_OF_CONDUCT.md - Release checklist:
docs/RELEASE_CHECKLIST.md
License
MIT