Claude Code
Claude Code is Anthropic’s agentic coding CLI: it reads your files, runs your
commands, and edits your repository in a loop. It speaks the Anthropic Messages
API, so it points at the gateway’s messages surface and needs no proxy, plugin
or shim — only a base URL and a key.
/v1 —
the Anthropic client appends it itself. https://guardrails.vulnetix.com/anthropic/{orgUuid}/v1
is wrong and produces a 404. This is the single most common hand-configuration
mistake; vulnetix ai-firewall install claude-code gets it right for you.Why put Claude Code behind the firewall
- Your provider key never sits in the agent’s config. Claude Code carries your Vulnetix API key. Your Anthropic key stays in the KMS-encrypted BYOK vault and is decrypted just-in-time by the gateway, on the server side of the request.
- Every prompt the agent sends is screened by your guardrails — and for an agent, “prompt” means far more than what you typed. The contents of every file it reads and the output of every command it runs are fed back into the conversation as tool results, and those go through your guardrails too.
- Provider and model policy is enforced centrally. Claude Code cannot silently switch to a model your organisation has not approved: the decision is made at the gateway, on every request, not in a local config file a developer can edit.
Quick start
vulnetix ai-firewall key set anthropic --from-env ANTHROPIC_KEY
vulnetix ai-firewall install claude-code
That writes an env block into ~/.claude/settings.json — or into
<repo>/.claude/settings.json if you pass --scope project.
vulnetix ai-firewall install claude-code --scope project --dry-run
--dry-run prints the exact file and the exact block it would write, and changes
nothing.
Then make sure your Vulnetix API key is in the environment Claude Code inherits:
export VULNETIX_API_KEY=vlx_...
vulnetix ai-firewall install shell adds a managed block to your shell rc that
exports VULNETIX_API_KEY for you, so every client on the machine picks it up.Claude Code reads three environment variables. Set them either in your shell
profile, or in the "env" key of .claude/settings.json.
Option A — shell profile (~/.zshrc, ~/.bashrc,
~/.config/fish/config.fish):
export ANTHROPIC_BASE_URL="https://guardrails.vulnetix.com/anthropic/{orgUuid}"
export ANTHROPIC_AUTH_TOKEN="$VULNETIX_API_KEY"
export ANTHROPIC_API_KEY=""
Option B — .claude/settings.json (user-level at ~/.claude/settings.json,
or project-level at <repo>/.claude/settings.json):
{
"env": {
"ANTHROPIC_BASE_URL": "https://guardrails.vulnetix.com/anthropic/{orgUuid}",
"ANTHROPIC_AUTH_TOKEN": "vlx_...",
"ANTHROPIC_API_KEY": ""
}
}
Three things to get right:
- No
/v1onANTHROPIC_BASE_URL. ANTHROPIC_AUTH_TOKENis your Vulnetix API key, not an Anthropic key.ANTHROPIC_API_KEYmust be set to an explicit empty string. If it still holds a stale Anthropic key, that key conflicts with the auth token and you get confusing authentication behaviour.
/logout first. A cached login takes precedence over these settings, and your
traffic will keep going straight to Anthropic — bypassing the firewall entirely.How it works
Claude Code sends POST /v1/messages to
https://guardrails.vulnetix.com/anthropic/{orgUuid} — the gateway’s messages
surface. The gateway authenticates the Vulnetix API key to your organisation,
applies provider and model policy, runs your guardrails over every text segment in
the request, decrypts your Anthropic key from the vault, and forwards the call.
Prompts and completions are never logged.
No local proxy is required. Claude Code is talking to the gateway directly, over the same protocol it would use to talk to Anthropic.
Verify
Inside Claude Code:
/status
It prints the auth token source and the base URL it is using. You are looking for:
Auth token: ANTHROPIC_AUTH_TOKEN
Base URL: https://guardrails.vulnetix.com/anthropic/{orgUuid}
If the base URL is https://api.anthropic.com — or the auth source is an OAuth
login rather than ANTHROPIC_AUTH_TOKEN — you are not going through the firewall.
Run /logout, restart the session, and check again.
From outside:
vulnetix ai-firewall status
Claude Code should show as wired, with no bypasses_firewall warning.
Limitations
Once wired, every model request Claude Code makes goes through the firewall — including the small-model calls it makes for background work, because those use the same base URL and credential.
Two honest caveats:
- The arguments the model generates for a tool call are not scanned. Prompt content and tool results are; the tool-call arguments the model emits are not.
- A developer who unsets
ANTHROPIC_BASE_URL, or logs back in with/login, is talking to Anthropic directly again. The firewall is a control, not a cage.vulnetix ai-firewall statusexists so you can find that machine — itsbypasses_firewallcheck is exactly this case.
Common errors
401 — invalid Vulnetix API key
{
"type": "error",
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "invalid Vulnetix API key"
}
}
Almost always the two-keys confusion: ANTHROPIC_AUTH_TOKEN is holding an
Anthropic key (sk-ant-…) instead of your Vulnetix API key. Your provider
key belongs in the vault, never in the agent.
Fix:
- Put your Anthropic key in the vault:
vulnetix ai-firewall key set anthropic --from-env ANTHROPIC_KEY. - Set
ANTHROPIC_AUTH_TOKENto your Vulnetix API key. - Set
ANTHROPIC_API_KEYto an explicit empty string. - Restart the Claude Code session and confirm with
/status.
403 — provider_key_missing
{
"type": "error",
"error": {
"type": "permission_error",
"code": "provider_key_missing",
"message": "no Anthropic API key configured for your organisation: add one with 'vulnetix ai-firewall key set anthropic' or at https://www.vulnetix.com/vdb-ai-firewall#byok"
}
}
You are authenticated, but your organisation has no Anthropic key in the vault, so the gateway has nothing to forward the request with.
Fix:
export ANTHROPIC_KEY=sk-ant-...vulnetix ai-firewall key set anthropic --from-env ANTHROPIC_KEYvulnetix ai-firewall status— theanthropicrow should now show a stored key.
403 — model_not_allowed
{
"type": "error",
"error": {
"type": "permission_error",
"code": "model_not_allowed",
"message": "model claude-opus-4-1 is not in the organisation allowlist"
}
}
Your organisation runs an allowlist for this provider, and the model Claude Code
asked for is not on it. (A model that is explicitly denied returns
model_denied instead.)
Fix:
- Ask your administrator which models are allowed, or run
vulnetix ai-firewall get. - Point Claude Code at an approved model with
/modelinside the session. - If the model should be allowed, an administrator adds it to the policy.
404 — unsupported_api
{
"type": "error",
"error": {
"type": "not_found_error",
"code": "unsupported_api",
"message": "provider openai does not support the Anthropic Messages API (POST /v1/messages). Use POST /v1/chat/completions for openai, or point your Anthropic client at a provider that serves the Messages API: https://guardrails.vulnetix.com/anthropic/{orgUuid} (note: no /v1 suffix — the Anthropic SDK appends it)"
}
}
Two causes, and the message distinguishes them: either the provider slug in your
base URL is not anthropic, or you appended /v1 and the client appended another
one on top.
Fix:
- Check
ANTHROPIC_BASE_URLwith/statusinside Claude Code. - It must be exactly
https://guardrails.vulnetix.com/anthropic/{orgUuid}— the sluganthropic, and no trailing/v1. - Re-run
vulnetix ai-firewall install claude-codeto have the CLI write it correctly.