Continue
Continue is an open-source AI assistant that runs as an extension inside VS Code and
the JetBrains IDEs. Unlike the editors that ship their own models, Continue is
model-agnostic by design: you tell it which provider to call in
~/.continue/config.yaml, and it calls it. That makes it one of the cleanest
clients to put behind the firewall — everything it sends goes through the endpoint
you configure.
VULNETIX_API_KEY the way Codex or Aider can. The CLI therefore writes your
Vulnetix API key literally into ~/.continue/.env, with mode 600. This is
Continue’s design, not ours. Treat that file as a credential: never commit it, and
rotate the key if the machine is lost.Why put Continue behind the firewall
- Your provider key never sits in the extension’s config. Continue carries your Vulnetix API key. Your OpenAI key stays in the KMS-encrypted BYOK vault and is decrypted just-in-time by the gateway, on the server side of the request. If the laptop is lost, you rotate one Vulnetix key — you do not rotate an OpenAI key that was sitting in a dotfile.
- 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. Continue 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 openai --from-env OPENAI_KEY
vulnetix ai-firewall install continue --model gpt-4o-mini
That writes two files:
~/.continue/config.yaml— a model entry pointing at your organisation’s gateway base URL.~/.continue/.env— your Vulnetix API key, written literally,chmod 600.
The --model you pass is validated against your organisation’s policy before
either file is touched, so you cannot wire a model the gateway would refuse at
request time.
vulnetix ai-firewall install continue --dry-run
--dry-run prints both files and the exact blocks it would write, and changes
nothing.
Restart your IDE — or reload the Continue extension — so it re-reads the config.
Add a model entry to ~/.continue/config.yaml that names the gateway as an
OpenAI-compatible endpoint:
models:
- name: Vulnetix AI Firewall (openai)
provider: openai
model: gpt-4o-mini
apiBase: https://guardrails.vulnetix.com/openai/{orgUuid}/v1
apiKey: ${{ secrets.VULNETIX_API_KEY }}
roles:
- chat
- edit
- apply
This is the entry vulnetix ai-firewall install continue writes, verbatim. The
name is what the CLI reconciles on — keep it if you want install and
uninstall to keep managing this entry for you.
And put the key in ~/.continue/.env:
VULNETIX_API_KEY=vlx_...
chmod 600 ~/.continue/.env
Three things to get right:
provider: openaidescribes the wire protocol, not the vendor you are billing. It staysopenaieven when the gateway is forwarding to a different provider — it is how Continue knows to speak OpenAI chat.- The base URL does end in
/v1— this is the OpenAI shape. apiKeyresolves to your Vulnetix API key, not an OpenAI key.
vulnetix ai-firewall install continue — the
CLI writes whatever the current schema is, and --dry-run will show you it before
it does.How it works
Continue sends POST /v1/chat/completions to
https://guardrails.vulnetix.com/openai/{orgUuid}/v1 — the gateway’s chat
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 provider key from the vault, and forwards the call.
Prompts and completions are never logged.
No local proxy is required. Continue is talking to the gateway directly, over the same protocol it would use to talk to OpenAI.
Because chat is the surface almost every provider serves, Continue is not tied to
openai the way Codex is. Point apiBase at openrouter, groq, mistral,
deepseek or any other chat provider — as long as your organisation has a stored
key for it — and set model to that provider’s own model string. Model names pass
through the gateway verbatim: gpt-4o-mini on openai, openai/gpt-4o-mini on
openrouter.
Verify
vulnetix ai-firewall status
Continue should show as wired:
clients
continue wired ~/.continue/config.yaml
https://guardrails.vulnetix.com/openai/{orgUuid}/v1
points elsewhere means config.yaml exists but its apiBase names a different
endpoint — api.openai.com, or another gateway. That client raises the
bypasses_firewall check, and it is the one to act on.
Then, in the IDE, open a Continue chat, select the model you wired, and send a message. A model that answers is proof of the whole path: key, base URL, policy and vault.
Limitations
Once wired, nothing about Continue bypasses the firewall. Chat, edit and
autocomplete all use the models defined in config.yaml, so every request goes to
the endpoint you configured. Continue ships no built-in models of its own — this is
the property Cursor lacks.
Two honest caveats:
- The arguments the model generates for a tool call are not scanned. Prompt content and tool results are.
- The key is a literal string in
~/.continue/.env. Anyone with read access to that file has your Vulnetix API key until you rotate it. It is a Vulnetix key rather than a provider key, which limits the blast radius to your gateway — but it is still a credential on disk.
A developer can also edit config.yaml and point apiBase somewhere else. The
firewall is a control, not a cage; vulnetix ai-firewall status and its
bypasses_firewall check exist so you can find that machine.
Common errors
401 — invalid Vulnetix API key
{
"error": {
"message": "invalid Vulnetix API key",
"type": "authentication_error",
"code": "invalid_api_key"
}
}
The two-keys confusion: the value in ~/.continue/.env is an OpenAI key
(sk-…) instead of your Vulnetix API key. The provider: openai line in the
config makes this an easy mistake — it names the protocol, and tempts you to
supply an OpenAI credential. The gateway authenticates you with the Vulnetix key
and supplies the OpenAI key itself, from the vault.
Fix:
- Store your OpenAI key in the vault:
vulnetix ai-firewall key set openai --from-env OPENAI_KEY. - Put your Vulnetix API key in
~/.continue/.envasVULNETIX_API_KEY=vlx_.... chmod 600 ~/.continue/.env.- Reload the Continue extension so it re-reads the file — it does not watch it.
403 — provider_key_missing
{
"error": {
"message": "no OpenAI API key configured for your organisation: add one with 'vulnetix ai-firewall key set openai' or at https://www.vulnetix.com/vdb-ai-firewall#byok",
"type": "permission_error",
"code": "provider_key_missing"
}
}
You are authenticated, but your organisation has no key in the vault for the
provider named in your apiBase, so the gateway has nothing to forward the request
with.
Fix:
export OPENAI_KEY=sk-...vulnetix ai-firewall key set openai --from-env OPENAI_KEYvulnetix ai-firewall status— that provider’s row should now show a stored key.
vulnetix ai-firewall install continue refuses to wire a provider with no stored
key, so this error usually means the key was removed after the config was written.
403 — model_not_allowed
{
"error": {
"message": "model gpt-4.5-preview is not in the organisation allowlist",
"type": "permission_error",
"code": "model_not_allowed"
}
}
Your organisation runs an allowlist for this provider, and the model in
config.yaml is not on it. (A model that is explicitly denied returns
model_denied instead.)
Fix:
- Run
vulnetix ai-firewall getto see which models your policy permits. - Re-wire with an approved model:
vulnetix ai-firewall install continue --model gpt-4o-mini. The CLI validates the model against policy before writing, so this cannot leave you in the same state. - If the model should be allowed, an administrator adds it to the policy.
404 — unsupported_api
{
"error": {
"message": "provider anthropic does not support the OpenAI Chat Completions API (POST /v1/chat/completions). Use POST /v1/messages for anthropic: https://guardrails.vulnetix.com/anthropic/{orgUuid}",
"type": "not_found_error",
"code": "unsupported_api"
}
}
Continue’s provider: openai block speaks OpenAI chat, so apiBase must name a
provider that serves the chat surface. anthropic does not — it serves messages
only. The same code also appears when the /v1 suffix is missing: the OpenAI shape
requires it, unlike Anthropic’s.
Fix:
- Open
~/.continue/config.yaml. - Set
apiBasetohttps://guardrails.vulnetix.com/{provider}/{orgUuid}/v1, where{provider}serveschat—openai,openrouter,groq,mistral,deepseek,xai,together,fireworks,alibaba,moonshotorminimax. - Keep the trailing
/v1. - Reload the extension.
The CLI catches this class of mistake locally, before you send a request, as the
wire_unsupported check.