Enforcer Gateway
Local LLM reverse proxy on port 8787.
Point coding agents at it as base_url.
It talks only to the Integrations Gateway — never to the Platform Gateway.
base_url
instead. See client settings.
Three gateways
| Product | Local port | Audience |
|---|---|---|
| Platform Gateway | :5145 | Mobile Approver and IDE host enforcers (JWT azp includes airlock-enforcer) |
| Integrations Gateway | :5190 | EnforcerApp + PAT and Enforcer Gateway artifact submit / wait |
| Enforcer Gateway | :8787 | LLM reverse proxy. Authenticate to IGW with a workspace Client ID + secret (no PAT, no consent). |
What it does
- Forwards OpenAI, Anthropic, Azure OpenAI, Codex Responses, and Bedrock Converse/Invoke paths to the real provider. The inbound provider key is forwarded unchanged — this is not a vault.
- Inspects tool calls, wraps a HARP
tool-call-approvalartifact to workspace members who have Mobile Approver keys (not the whole org), waits for a mobile decision, and verifies the decision signature before releasing the response. - Returns
503 airlock_not_configureduntil an Integrations Gateway URL and a workspace Client ID + secret are available (process env, or a key binding plus the secrets file). - Does not pair with a phone and does not use a pairing file, routing token, or pairing AES key. Host IDE enforcers still pair; this process does not.
- Does not implement HTTP CONNECT. Do not use it as a generic HTTP proxy.
Workspace routing (provider-key bind)
A governance workspace is a credential and policy boundary, not a folder on disk.
Enforcer Gateway never stores a workspace Guid. It maps each request to a workspace
Client ID (alc_…), and Integrations Gateway resolves that to the workspace.
- On
http://127.0.0.1:8787/config(loopback only), bind the SHA-256 of a provider API key (or Bedrock Access Key ID) to a workspace Client ID. After save, only the last 4 characters are shown. - If any bindings exist, an unknown inbound key is
401 unknown_provider_key— there is no default workspace. - If the bind table is empty, the process-level Client ID +
Airlock__ClientSecretis used (same as a single-workspace install). - Client secrets are not stored in SQLite. Optional per-Client-ID secrets go in
airlock-enforcer-secrets.json. Env is the fallback when the bound Client ID matches the process Client ID. - Escape hatch: prefix the provider path, for example
http://127.0.0.1:8787/ws/engineering/v1/chat/completions. If both the path label and the inbound key bind, they must name the same Client ID or the proxy returns403 workspace_bind_conflict.
Auth to Integrations Gateway
Mint a workspace credential in Platform.App (workspace Owner or Maintainer,
or an organization Owner).
Point Enforcer Gateway at IGW with Airlock__GatewayUrl
and put Client ID in config (or a key binding) and the secret in env or the secrets file.
Approvals wrap to active workspace members, not every org member.
Third-party Enforcer Apps still use Client ID + secret plus PAT; that path is unchanged.
See Organizations
and Airlock Apps.