# Reported issues for mcp-airlock

Pod holds 9 of 9 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [mcp-airlock](/mcp/mcp-airlock).

## Most discussed

### OTLP span exporter behind an env var

Spans are produced already (`execute_tool <tool>` with `gen_ai.*` attributes, principal, verdict) but the only exporter wired in is the console one writing to `--otel-file`. Anyone running a collector has to patch the source.

**What to do**

`src/mcp_airlock/__main__.py`, `setup_otel()`. Add an OTLP HTTP exporter when `OTEL_EXPORTER_OTLP_ENDPOINT` is set, keeping the file exporter as it is so both can be on at once. Use `BatchSpanProcessor` for OTLP, not `SimpleSpanProcessor`. The dependency…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/1) · 2026-09-15 · open · 1 comment

### count_arg counts a JSON-encoded list as one object

`Policy.count_objects` takes `len()` of the `count_arg` argument when it is a list, tuple, set or dict, and 1 for anything else. A list sent as a JSON string (`ids: "[1,2,3,4,5,6]"`) counts as one object, but the SDK upstream decodes the string into a list before it validates it. `blast_radius.max_per_call` and the per-principal window are bypassed that way. Found while reviewing #12, same cause as the `not_in` bypass fixed there: the policy looks at the raw string, the upstream at the decoded…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/24) · 2026-10-01 · closed · 0 comments

### requestState does not carry the approval mode

The token binds principal, tool, argument hash, environment and upstream, but not the approval mode. Replicas that share `AIRLOCK_SECRET` and the store but run different modes accept each other's tokens: a `requestState` issued by a replica in `oob` mode is accepted in-band by a replica in `inband` mode. Reproduced with two instances sharing the secret and a store: the `oob` one answers pending, the `inband` one runs the call (`tier.L2.confirmed`, one real delete). The postgres e2e stack runs…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/23) · 2026-10-01 · closed · 0 comments

### Warn about risky configuration at startup

Several configurations start fine and are weaker than they look. Log a warning for each at startup:

* no identity configured (no JWT secret, no JWKS URL, no trusted header): every call gets 401
* `AIRLOCK_JWKS_URL` without `AIRLOCK_JWT_AUDIENCE`
* `AIRLOCK_JWT_SECRET` shorter than 32 bytes
* `AIRLOCK_TRUST_PRINCIPAL_HEADER=1` together with JWT settings: a request with no `Authorization` header is trusted on the header alone
* `AIRLOCK_STORE_DSN` set without `AIRLOCK_SECRET`: replicas sign with…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/15) · 2026-10-01 · closed · 0 comments

### Size limits, shutdown hook, blocking call on /approve

* there is no limit on the request body or on the upstream response; `self.http.post` reads the whole answer into memory before the output cap runs
* `Airlock` has no shutdown hook: the httpx client, the audit sinks and the Postgres audit connection are never closed
* `approve_submit` calls `identity.resolve` directly; with `AIRLOCK_JWKS_URL` that is a blocking fetch on the event loop (`handle` already uses `asyncio.to_thread`)

Do: `AIRLOCK_MAX_REQUEST_BYTES` (default 1 MiB, 413 above it) and…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/14) · 2026-10-01 · closed · 0 comments

### Audit `detail` field is not redacted

`audit._row` redacts `args` only. `detail` carries upstream error text (`catalog.unavailable`, `upstream unreachable: ...`, `postprocess_error`) and can contain credentials, for example a URL with a token in the query string.

Run string values in `detail` through `scrub` and dict values through `redact`, for both sinks.

Test: a deny with a bearer token in the error text reaches the JSONL file and the Postgres table as `[REDACTED]`.

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/10) · 2026-10-01 · closed · 0 comments

### Approve link can be bypassed by answering the prompt in-band

With `AIRLOCK_APPROVAL_WEBHOOK` set, a caller that holds `requestState` can repeat the call with `inputResponses: {"airlock-confirm": {"action": "accept", "content": {"confirm": true}}}`. The call executes and the approve link is never opened. Reproduced on main with an L2 `delete_service` call: one real delete, no `/approve` request.

The README says the agent cannot approve its own call. With a webhook configured that is not true.

Add `AIRLOCK_APPROVAL_MODE`:

* `oob`: only the approve link…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/7) · 2026-10-01 · closed · 0 comments

### Approval webhook URL is written to the log when delivery fails

`approvals.notify` logs `str(e)` of the httpx error. For a failed POST that string contains the full URL, so a Telegram bot token (`.../bot<token>/sendMessage`) or a Slack webhook path ends up in the log. Reproduced on main with a 401 from a mock transport.

Log the exception class and the HTTP status only. No URL, no response body.

Test: a transport that answers 401 for `https://api.telegram.org/bot123:SECRET/sendMessage`. `SECRET` must not appear in `caplog.text` and `notify` must still…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/6) · 2026-10-01 · closed · 0 comments

## Most recent

### Helm chart for running the proxy in a cluster

The usual place for this proxy is next to an MCP server in Kubernetes, but the only deployment artifacts are a Dockerfile and a `docker run` line. A small chart would remove most of the work for anyone trying it in a cluster.

**What to do**

A `charts/mcp-airlock/` chart, deliberately plain: Deployment, Service, ConfigMap for the policy file, and that is close to it. Notes on what matters:

* The policy goes in a ConfigMap mounted at `/data/policy.yaml`; `--policy` already points there in the…

[Read the thread](https://github.com/Shalimov04/mcp-airlock/issues/3) · 2026-09-15 · open · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/Shalimov04/mcp-airlock/issues).
