Agent-Airlock is pre-1.0, so support is stated as a rule rather than a list: security
fixes land on the current minor line only. A fix ships as a new patch on that line and is
not backported below it. Upgrade to the newest patch of the current line. The current line
is 0.10.x.
| Version | Supported |
|---|---|
Current minor line (0.10.x) |
✅ |
| Any earlier minor line | ❌ |
The rule is the load-bearing part; the line number is named once, here, and
tests/test_version_consistency.py fails the build if it stops matching the version in
pyproject.toml. This table once named a minor line two releases behind the one that
shipped, which told a reporter on a supported version that they were unsupported.
| Fixed in | Issue |
|---|---|
| v0.8.74 | SecurityPolicy.freeze() silently dropped five security fields (affects v0.5.7–v0.8.73, only when freeze() is called) |
| Result | What it is |
|---|---|
| Matched-pair multi-harness prompt injection | A null, published as one. On the 2026-10-03 re-run, claude-code 2.1.288 and codex 0.154.0 (pinned to gpt-6-astra, the 2026-09-20 model) each ran the exfiltration-shaped script 0/36, and each also ignored the benign twin 0/36: all four arms are zero (0/144), so neither zero can be read as resistance. Both finished the task in 72 of 72 cells, so each zero rests on all 36 cells and its 95% upper bound is 9.6% (on 2026-09-20 codex finished 52 of 72, bound 13.8%). Explicitly not an injection-resistance finding. Includes every earlier run and why each was superseded. |
Process-level containment for agents is being given away now. NVIDIA's OpenShell and Cisco's DefenseClaw both ship deny-by-default sandboxing around the process an agent's tools run in, and Amazon's Cedar gives away the policy language for expressing who may do what. None of these is a competitor airlock is trying to argue with, and the honest starting point is that if you are not running one of them, do that before you reach for this. They close a larger and more commonly exploited class of problem than argument validation does.
What they solve. They bound what a process can reach. A contained tool process cannot
open a socket to an attacker's host, read ~/.aws/credentials, or write outside its
workspace, regardless of what the model asked it to do or how the request was phrased. That
is containment in the operating-system sense, and it holds even when every layer above it has
been fooled — which is the property that makes it valuable and the reason it belongs at the
bottom of any agent stack. Cedar covers the adjacent question: given an authenticated
principal and a resource, is this action permitted at all.
What they do not solve. They bound the blast radius of a call; they do not check whether
the call is the one the contract allows. A sandbox has no opinion about
transfer(amount=-1), about an account_id the model invented that happens to be a valid
string, about a session handle minted for another tenant, or about six extra parameters
that were never in the tool's signature. Every one of those is a well-formed, in-policy,
fully-contained call that does the wrong thing with the authority it legitimately has. Cedar
is the sharpest illustration: it answers may this principal call this action on this
resource, and answers it well — but the arguments are the part it does not model, and an
authorized principal calling an authorized action with fabricated arguments passes.
That gap is the whole of airlock's wedge, and it is deliberately narrow: a deny-by-default
type-checker and contract layer for the arguments themselves, in-process, at the call
boundary. The two compose in the obvious direction — containment bounds what a call can do,
airlock refuses the call before it is made — and they are complementary rather than
overlapping. Note the ordering that follows from that: airlock validates in the calling
process, before dispatch. That holds under sandbox=True as well (since v0.10.6): the
arguments are validated in the parent and the sandbox is handed the already-validated
values, so Annotated validators (SafePath, SafeURL, HandleField) apply on both
paths and refuse with the same BlockReason. Before v0.10.6 they did not run on the
sandbox path at all. What is still true is the direction: validation happens on the parent
side of the boundary, so nothing inside the sandbox can consult the handle ledger or mint
a handle.
Stated plainly, because a security library that cannot say where it does not help is not one worth trusting on where it does:
- You need containment, not validation. If the risk you are managing is "this tool could
exfiltrate data or touch the host", a sandbox is the answer and airlock is not a substitute
for one.
sandbox=Truedelegates to E2B, Modal, or Docker precisely because airlock does not implement isolation itself. - You cannot run code in the agent's process. airlock is a decorator. If the tools are behind someone else's server and you can only intervene on the wire, you need a proxy or a gateway; see the MCP-gateway comparison in the README.
- The open question is who may authorize an action. That is an authorization model — Cedar, or the propose-versus-authorize architectures. airlock's escalation verdict routes to an approver you supply; it does not decide policy for your organisation. The full comparison is in the README's propose-versus-authorize section and is not repeated here.
- You want a human-approval UI. airlock's approver is a callable. There is no prompt, no pending-request queue, and no approval store.
- Your tools take no structured arguments. A single free-text
querystring has almost no contract to check. The value of argument validation scales with how much structure the arguments have.
Triaging a disclosed CVE rather than reporting a new one? See
docs/cve-triage.md— it defines what this library can and cannot guard, and the disposition vocabulary everycve-responseissue is closed with. Most disclosed MCP CVEs are server-side authorization defects that a tool-call contract layer is structurally not in the path of; that page says so explicitly rather than leaving them open.
If you discover a security vulnerability in Agent-Airlock, please report it responsibly:
- Do NOT create a public GitHub issue
- Report it privately via GitHub Security Advisories ("Report a vulnerability" on the repo's Security tab), or email sattyamjain96@gmail.com
- Include:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if any)
We aim to respond within 48 hours and will work with you to understand and address the issue.
Last audit: 2026-08-22 (was 2026-01-31 — the block below had gone seven months stale and still listed findings that no longer exist; it is now re-run and re-dated at release).
Re-run 2026-08-22 with bandit -c pyproject.toml -r src/agent_airlock/, which is the exact
command CI runs — -c makes the [tool.bandit] block in pyproject.toml authoritative.
| Metric | Result |
|---|---|
| Lines of code scanned | 48,420 |
| High severity | 0 |
| Medium severity | 0 |
| Low severity | 0 |
# nosec suppressions in src/ |
29, every one carrying a stated reason (same line or the line above) |
[tool.bandit] sets no skips — B101 (assert_used) in particular is deliberately not
suppressed globally, because it once caught two narrowing asserts in the CIMD trust-anchor
guard that python -O would have stripped. Suppression is per-site and must carry a reason.
The B110 / B105 findings this table used to list no longer appear in the run. The honest statement is that they do not appear — the table reports what the scanner returns today, not a reconstruction of why each historical finding cleared.
The installed core is Pydantic-only — pydantic>=2.0,<3.0, plus tomli on Python 3.10.
That is enforced by the bare-install CI job rather than asserted here, and it is the
reason the dependency-vulnerability surface is close to nil: there are two runtime
dependencies to scan. Optional extras pull more, and are the caller's choice to audit.
All regex patterns have been reviewed for Regular Expression Denial of Service vulnerabilities:
| Pattern | Risk | Mitigation |
|---|---|---|
| Low | Word boundaries limit backtracking | |
| PHONE | Safe | Fixed-width numeric patterns |
| SSN | Safe | Fixed-width pattern |
| CREDIT_CARD | Safe | Fixed-width pattern |
| IP_ADDRESS | Safe | Bounded repetition {3} |
| API_KEY | Safe | Specific prefixes, bounded lengths |
| AWS_KEY | Safe | Fixed pattern |
| PASSWORD | Low | Prefix anchors limit search space |
| PRIVATE_KEY | Safe | Fixed pattern |
| JWT | Low | Bounded by prefix and dot separators |
| CONNECTION_STRING | Low | Protocol prefixes limit matching |
Recommendation: For untrusted input, consider setting max_output_chars to limit regex processing time.
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: Input Validation (Ghost Argument Stripping) │
│ - Removes LLM-hallucinated parameters │
│ - Strict mode rejects unknown arguments │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: Schema Validation (Pydantic V2 Strict Mode) │
│ - No type coercion ("100" → int fails) │
│ - Self-healing error responses with fix_hints │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 3: Policy Enforcement (RBAC) │
│ - Tool allow/deny lists │
│ - Rate limiting (token bucket algorithm) │
│ - Time-based restrictions │
│ - Agent identity verification │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 4: Execution Isolation (E2B Sandbox) │
│ - Firecracker MicroVM isolation │
│ - Network isolation │
│ - Resource limits │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Layer 5: Output Sanitization │
│ - PII detection and masking │
│ - Secret detection and masking │
│ - Output truncation (cost control) │
└─────────────────────────────────────────────────────────────┘
When using sandbox=True, functions are serialized using cloudpickle for execution in E2B sandboxes.
Risk: Pickle deserialization can execute arbitrary code.
Mitigation:
- Deserialization only occurs inside the isolated E2B MicroVM
- The MicroVM is destroyed after its call (since 0.10.17; it used to be reused)
- The MicroVM cannot reach the host's filesystem or memory. Its outbound network is E2B's default, which allows internet access
- The host never deserializes pickled data from the sandbox: results come back as JSON
Best Practice:
# SECURE: sandbox_required=True prevents local fallback
@Airlock(sandbox=True, sandbox_required=True)
def dangerous_operation(code: str) -> str:
exec(code) # Only runs in MicroVM
return "done"The token bucket rate limiter uses floating-point time comparisons.
Risk: Potential timing attacks to probe rate limit state.
Mitigation:
- Rate limit responses include consistent timing
- No early exits that could leak state information
- Reset times are rounded to avoid precision-based attacks
Debug logs could potentially leak sensitive information.
Mitigation:
- Parameter names are filtered against a blocklist before logging
- Sensitive parameter values are never logged
- Audit logs redact sensitive fields automatically
Filtered parameter names:
- password, passwd, pwd, secret, token
- key, api_key, apikey, auth, authorization
- credential, credentials, private_key, privatekey
- access_token, refresh_token, session, cookie
- ssn, credit_card, card_number
Regex-based PII detection has inherent limitations:
Known Limitations:
- May not detect obfuscated PII (e.g., "john at example dot com")
- Language-specific patterns (non-US phone formats)
- Context-dependent sensitivity (public vs private IP addresses)
Recommendations:
- Use workspace-specific PII configs for custom patterns
- Combine with application-level data classification
- Regular review of masking effectiveness
Audit logs contain tool call metadata.
Best Practices:
- Store audit logs in a secure, access-controlled location
- Implement log rotation and retention policies
- Encrypt logs at rest for sensitive environments
- Consider log forwarding to a SIEM system
from agent_airlock import Airlock, AirlockConfig, SecurityPolicy
# 1. Enable strict mode to reject unknown arguments
config = AirlockConfig(
strict_mode=True, # Reject ghost arguments
sanitize_output=True, # Enable output sanitization
mask_pii=True, # Mask PII in output
mask_secrets=True, # Mask secrets in output
max_output_chars=20000, # Limit output size
enable_audit_log=True, # Enable audit logging
)
# 2. Define restrictive policy
policy = SecurityPolicy(
allowed_tools=["read_file", "search"], # Allowlist, not blocklist
denied_tools=["delete_*", "drop_*"], # Extra protection
rate_limits={"*": "100/minute"}, # Global rate limit
)
# 3. Use sandbox for dangerous operations
@Airlock(
config=config,
policy=policy,
sandbox=True, # Execute in isolation
sandbox_required=True, # Never fall back to local
)
def execute_code(code: str) -> str:
...| Variable | Purpose | Default |
|---|---|---|
E2B_API_KEY |
E2B sandbox authentication, when no key is set in code | None |
AIRLOCK_UNKNOWN_ARGS |
Unknown-argument mode (block, strip_and_log, strip_silent) |
strip_and_log |
AIRLOCK_AUDIT_LOG_PATH |
Audit log file, when no audit_log_path is set in code or TOML |
airlock_audit.json |
AIRLOCK_STRICT_MODE |
Deprecated; true maps to AIRLOCK_UNKNOWN_ARGS=block |
unset |
AIRLOCK_MAX_OUTPUT_TOKENS |
Deprecated; nothing has ever applied it | 5000 |
Agent-Airlock helps with GDPR compliance through:
-
Data Minimization (Article 5)
- Output truncation limits data exposure
- Ghost argument stripping prevents over-collection
-
Purpose Limitation (Article 5)
- Policy engine restricts tool access by purpose
- Audit logs track data access
-
Data Protection by Design (Article 25)
- PII detection and masking enabled by default
- Defense-in-depth architecture
Your Responsibilities:
- Configure PII masking appropriate for your data categories
- Implement appropriate audit log retention (default: no automatic deletion)
- Ensure lawful basis for processing data through AI agents
- Document AI agent data processing in your privacy policy
Agent-Airlock supports CCPA compliance through:
-
Right to Know
- Audit logs record all tool calls and data access
- Configure log retention for compliance window
-
Right to Delete
- Implement session/conversation clearing in your application
- Audit logs can be purged per retention policy
-
Security Requirements
- Multiple security layers protect personal information
- Encryption recommended for audit logs at rest
For healthcare applications:
-
Technical Safeguards
- Enable all PII masking features
- Use E2B sandbox for PHI processing
- Configure workspace-specific PII patterns for PHI
-
Audit Controls
- Enable audit logging with extended retention
- Forward logs to secure SIEM system
- Implement access monitoring
-
Access Controls
- Use strict policy with role-based tool access
- Implement agent identity verification
Note: Agent-Airlock is not HIPAA-certified. Consult healthcare compliance experts for your specific use case.
Agent-Airlock supports SOC 2 compliance through:
| Trust Principle | Support |
|---|---|
| Security | Policy engine, sandbox isolation, input validation |
| Availability | Rate limiting, resource controls |
| Processing Integrity | Schema validation, audit logging |
| Confidentiality | PII/secret masking, output sanitization |
| Privacy | GDPR/CCPA features above |
| Data Type | Purpose | Storage |
|---|---|---|
| Function signatures | Schema generation | In-memory only |
| Call arguments | Validation, audit | Audit log (if enabled) |
| Tool outputs | Sanitization | Audit log (sanitized) |
| Timestamps | Rate limiting, audit | In-memory + audit log |
| Agent IDs | Policy enforcement | Audit log |
Default behavior:
- In-memory data: Cleared when process exits
- Audit logs: Append-only, no automatic deletion
- Conversation state: TTL-based cleanup (default: 1 hour)
Recommendation: Implement application-level log rotation and retention policies.
LLM Request → Airlock Validation → [Audit Log] → Execution → Sanitization → Response
│ │
▼ ▼
Sensitive params PII/secrets
filtered from logs masked in output
If you believe Agent-Airlock security has been compromised:
- Isolate - Stop affected AI agents
- Collect - Preserve audit logs for analysis
- Report - Report privately via GitHub Security Advisories or email sattyamjain96@gmail.com
- Remediate - Apply patches when available
- Review - Assess policy and configuration
Subscribe to security advisories:
- Watch this repository for releases
- Check the CHANGELOG for security fixes
- Follow @sattyamjain for announcements
Agent-Airlock uses E2B for sandboxed execution:
- Firecracker MicroVM technology
- SOC 2 Type II certified
- See: https://e2b.dev/security
Input validation uses Pydantic V2:
- Strict mode prevents type coercion attacks
- Regular security updates
- See: https://github.com/pydantic/pydantic/security