Windsurf

Windsurf is an AI-first editor in the same family as Cursor. Where it lets you bring your own OpenAI-compatible endpoint, that endpoint can be the firewall: you set a base URL and a key in its settings panel, and the chat traffic that uses them is screened by your guardrails.

Warning

Windsurf is not fully firewalled, for the same structural reason as Cursor. It ships its own models and its own built-in completion features, and those do not use your configured key — that traffic never reaches the gateway and your guardrails never see it. Bringing your own endpoint governs the requests Windsurf routes through your key; it does not govern the editor’s native AI features.

If your control narrative says “every prompt our developers send is screened”, Windsurf breaks that claim, and no setting on this page fixes it.

Note We do not publish a click path for Windsurf’s settings panel, because it changes between releases and a stale menu path in a security product’s documentation is worse than none. Run vulnetix ai-firewall install windsurf — it prints the current instructions, with your organisation UUID already substituted into the base URL.

Why put Windsurf behind the firewall

For the traffic Windsurf does route through your key — the chat and agent requests where developers paste the things you actually worry about — the three properties hold:

  • Your provider key never sits in the editor’s config. Windsurf stores 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.
  • Every prompt Windsurf sends through your key is screened by your guardrails — including the file contents and command output it feeds back into the conversation as tool results.
  • Provider and model policy is enforced centrally. Windsurf cannot silently switch to a model your organisation has not approved through your key: the decision is made at the gateway, on every request.

Quick start

CLI

The CLI does not write Windsurf’s configuration — the editor keeps it in an internal store, not a file the CLI can safely edit. What it does is print the current, version-appropriate instructions:

vulnetix ai-firewall install windsurf

This writes nothing. It prints the steps with your gateway base URL already filled in, ready to paste into the settings panel. This is the instruction source to trust; prefer it over anything written down elsewhere, including this page.

Store your provider key first, whichever route you take:

vulnetix ai-firewall key set openai --from-env OPENAI_KEY
Manual

In Windsurf’s model / API-key settings panel:

  1. Enable the custom OpenAI-compatible provider.

  2. Set the API key to your Vulnetix API key — not an OpenAI key.

  3. Set the base URL to:

    https://guardrails.vulnetix.com/openai/{orgUuid}/v1
    

    The /v1 suffix is required here — this is the OpenAI shape.

  4. Add the model IDs you want — for example gpt-4o-mini. Windsurf does not fetch the list from your endpoint, so a model your organisation has not approved will be refused by the gateway at request time rather than hidden from the picker.

  5. Select one of your models explicitly, rather than leaving the editor to choose for you. A model Windsurf picks on your behalf may be one of its own, which does not go through the firewall.

How it works

For the traffic it routes to you, Windsurf 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. Windsurf is talking to the gateway directly, using its own OpenAI-compatible provider setting.

Verify

vulnetix ai-firewall status

Windsurf is reported as manual — the CLI does not manage its config and cannot read it back, so it cannot tell you whether the base URL override is in place. manual does not mean wired. The absence of a bypasses_firewall warning against Windsurf is not evidence that Windsurf is firewalled.

The end-to-end check has to happen in the editor. Open a chat, select the model you configured, and send a message that one of your guardrails should block. A 403 rendered in the chat pane, naming the rule that fired, is the only proof that this request went through the firewall. A normal answer to a normal question proves only that something answered.

Limitations

  • Windsurf’s own built-in AI features do not route through the firewall. The editor ships its own models; the key you configure governs the custom provider, not the native features. That traffic — including the code context those features send — never reaches the gateway.
  • A model the editor selects for you may not be yours. Tell developers to pick a model explicitly.
  • vulnetix ai-firewall status cannot verify Windsurf. It is manual, so it can never raise a bypasses_firewall warning for a misconfigured machine.
  • The arguments the model generates for a tool call are not scanned — as everywhere else in the firewall.

If you need an editor-integrated agent whose traffic is entirely firewalled, Continue is the closer fit: it is CLI-wired, it ships no models of its own, and everything it sends goes through your endpoint.

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 API-key field is holding an actual OpenAI key (sk-…) instead of your Vulnetix API key. The field is named for the protocol Windsurf speaks, not for the key it should contain: the gateway authenticates you with the Vulnetix key and supplies the OpenAI key itself, from the vault. Your provider key belongs in the vault, never in the editor.

Fix:

  1. Store your OpenAI key in the vault: vulnetix ai-firewall key set openai --from-env OPENAI_KEY.
  2. Replace the value in Windsurf’s API-key field with your Vulnetix API key.
  3. Retry a chat message.

403provider_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"
  }
}

Your Vulnetix key is valid, but your organisation has no key in the vault for the provider named in your base URL, so the gateway has nothing to forward the request with.

Fix:

  1. export OPENAI_KEY=sk-...
  2. vulnetix ai-firewall key set openai --from-env OPENAI_KEY
  3. vulnetix ai-firewall status — that provider’s row should now show a stored key.
  4. Retry in Windsurf.

403model_not_allowed

{
  "error": {
    "message": "model gpt-4.5-preview is not in the organisation allowlist",
    "type": "permission_error",
    "code": "model_not_allowed"
  }
}

You configured a model ID that your organisation’s allowlist does not include. (A model that is explicitly denied returns model_denied instead.) Because Windsurf’s model list is entered by hand rather than fetched from the gateway, nothing stops you naming a model that policy will refuse — unlike the CLI-wired clients, where --model is validated before anything is written.

Fix:

  1. Run vulnetix ai-firewall get to see which models your policy permits.
  2. Replace the model ID in Windsurf’s settings with an approved one.
  3. Select it explicitly in the model picker.

404unsupported_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"
  }
}

Windsurf’s custom provider speaks OpenAI chat, so its base URL 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 from the base URL: the OpenAI shape requires it.

Fix:

  1. Open the model / API-key settings panel.
  2. Set the base URL to https://guardrails.vulnetix.com/{provider}/{orgUuid}/v1, where {provider} serves chatopenai, openrouter, groq, mistral, deepseek, xai, together, fireworks, alibaba, moonshot or minimax.
  3. Keep the trailing /v1.
  4. Retry a chat message.