Documentation
Route AI clients through a policy-enforcing gateway — provider and model allow/deny, content guardrails, PII redaction, and BYOK provider keys.
The AI Firewall is a hosted, OpenAI-compatible gateway. Your code points its base_url at it instead of at the provider, and every request is screened against the organisation’s policy — which providers may be called, which models, and what may appear in a prompt — before it is forwarded upstream.
The CLI wires the AI clients on a machine to that gateway, proves they are wired, and manages the policy the gateway enforces.
vulnetix ai-firewall key set openai --from-env OPENAI_API_KEY
vulnetix ai-firewall install
vulnetix ai-firewall status
https://guardrails.vulnetix.com/{providerSlug}/{orgUuid}/v1
└─ openai └─ your org
The organisation is a path component, not a header. That is a deliberate constraint: most SDKs let you override the base URL and nothing else. If the org travelled in an X-Organisation-UUID header, every client would need custom header support and most would be unable to use the firewall at all. As a path segment it works anywhere a base_url can be set — which is everywhere.
(The Package Firewall makes the opposite trade, carrying the org as the HTTP Basic username, because package managers all speak netrc and none of them let you rewrite a URL path.)
The gateway fronts 13 providers, each reached at its own slug:
| Slug | Provider | Request surface |
|---|---|---|
openai | OpenAI | OpenAI Chat, OpenAI Responses |
anthropic | Anthropic | Anthropic Messages |
mistral | Mistral | OpenAI Chat |
groq | Groq | OpenAI Chat |
deepseek | DeepSeek | OpenAI Chat |
xai | xAI | OpenAI Chat |
openrouter | OpenRouter | OpenAI Chat |
together | Together AI | OpenAI Chat |
fireworks | Fireworks AI | OpenAI Chat |
alibaba | Alibaba Cloud | OpenAI Chat |
moonshot | Moonshot AI | OpenAI Chat |
minimax | MiniMax | OpenAI Chat |
kiro | Kiro | Kiro |
All thirteen are available on every plan. Every provider but Kiro is called with a provider API key you store (BYOK); Kiro has no API key and is authorised by a stored sign-in instead (kiro login).
An organisation on the Pro plan or above can add its own provider: a server of its own that speaks OpenAI Chat, OpenAI Responses or Anthropic Messages. It is given a slug of its own and then goes through the same policy, guardrails and logging as the built-in providers. Add and delete them on the Connect tab of the AI Firewall page; the CLI does not create them. The slug must not be one of the 13 above, and a built-in slug always wins.
https.localhost or inside your network cannot be added.This is the part that trips everyone up. There are two credentials, and they are not interchangeable:
| Credential | Who holds it | What it does |
|---|---|---|
| Vulnetix API key | your machine, your CI | authenticates you to the gateway |
| Provider key (OpenAI, Anthropic, …) | the server, encrypted | authenticates the gateway to the provider |
A wired client sends Authorization: Bearer $VULNETIX_API_KEY. The gateway resolves your org from the URL, checks the request against policy, decrypts your provider key, swaps it into the outbound Authorization header, and forwards the call. The request that reaches OpenAI is authenticated with your OpenAI key — so billing stays direct with the provider, and there is no token markup.
The provider key never travels to a developer machine. It is stored write-only: no API returns it, and the CLI can only tell you whether one exists (BYOK). Kiro is the one provider with no API key: its stored credential is a Kiro sign-in, and the gateway mints a short-lived access token from it for each request.
vulnetix ai-firewall status checks for exactly this.Each stage below returns HTTP 403 with an OpenAI-shaped error body, so an SDK surfaces it as an ordinary permission error. The code tells you which stage stopped the request.
provider_denied.provider_key_missing.model_denied. A model that is merely unlisted fails with model_not_allowed, but only in allowlist mode — see below.priority, lowest first. A block match returns request_blocked naming the rule; a redact match rewrites the matched text and forwards; a flag match forwards and records that a rule matched.Full reference: block responses and exit codes.
The first allow entry for a provider turns that provider allowlist-only.
With no model entries, every model the provider offers is usable. Deny a model and it alone is blocked. But allow a model — even one — and the provider switches to allowlist mode: from that moment, any model not on the allow list is refused with model_not_allowed, without ever having been denied.
This is the single most surprising behaviour in the product, and the usual cause of “it worked yesterday”. vulnetix ai-firewall status flags a client whose pinned model would be refused this way. More in the policy reference.
The gateway serves four request surfaces. That matters because not every client speaks the OpenAI one:
/v1/chat/completions — OpenAI Chat: the OpenAI SDKs, LangChain, LlamaIndex, aider, Continue, Cursor, Windsurf./v1/messages — Anthropic Messages. Claude Code speaks only this./v1/responses — the OpenAI Responses API. Codex speaks only this: its wire_api setting no longer accepts anything else./v1/generateAssistantResponse — Kiro, for the Kiro IDE and CLI. The reply is an AWS event stream rather than Server-Sent Events. It is served only under the kiro slug, and a client sends just its Vulnetix API key to https://guardrails.vulnetix.com/kiro/{orgUuid}/v1.The CLI does not guess. It asks the server what the gateway proxies for each provider, and if a client needs a wire the gateway does not serve, install skips that client and says why rather than writing a configuration that would 404 at request time.
/v1/models is filtered by policy, so a client that autodiscovers models only ever sees ones it is permitted to call.
The dashboard can do policy. The CLI can do policy and the machine:
install writes the base URL and key into every AI client on the box — shell, project env, Claude Code, Codex, Continue, aider — and tells you what to paste into the ones that have no config file.status is the honest answer to “is this actually on?” It finds clients whose traffic is bypassing the firewall entirely, and guardrails that look enforced but are not.apply reconciles the whole policy from a file you can review and commit.snippet is the only route for the clients that environment variables cannot reach.inventory lists every tool, MCP server and skill the gateway has seen an agent carry — the list your rules are written against.