Model proxy
Expose an OpenAI, Anthropic, Gemini, Ollama, or custom text model through one local Chat Completions endpoint that SecureAI can test.
secureai proxy --config secureai.provider.yamlWhy the proxy exists
Model providers use different request bodies, authentication headers, and response shapes. The proxy accepts the stable OpenAI Chat Completions shape used by secureai test, translates the request, calls your provider, and returns normalised assistant text.
This supports text chat APIs that can be described by a preset or JSON mapping. Streaming-only, multimodal-only, binary, and non-HTTP models need an HTTP text adapter before SecureAI can test them.
Configure a provider
version: 1
listen: 127.0.0.1:8090
timeout: 60s
max_retries: 2
provider:
type: anthropic
endpoint: https://api.anthropic.com/v1/messages
model: claude-sonnet-4-5
api_key_env: ANTHROPIC_API_KEY
max_tokens: 1024export ANTHROPIC_API_KEY="..."
secureai proxy --config secureai.provider.yaml
# In another terminal
secureai test \
--target http://127.0.0.1:8090/v1/chat/completions \
--model proxied-modelProvider presets
| Type | Upstream API | Authentication default |
|---|---|---|
openai | OpenAI Chat Completions compatible JSON | Authorization: Bearer |
anthropic | Anthropic Messages | x-api-key |
gemini | Gemini generateContent | x-goog-api-key |
ollama | Ollama chat with streaming disabled | No key |
The endpoint is always explicit. This lets you use hosted providers, private gateways, regional endpoints, and local servers without SecureAI guessing a URL.
Map a custom API
Use type: custom when your model accepts JSON over HTTP but does not match a preset. The request template receives .Model, .Messages, and .Prompt. The json helper safely quotes values. response_path locates the returned text using dot and array indexes.
version: 1
provider:
type: custom
endpoint: https://models.example.com/infer
model: internal-chat-v3
api_key_env: INTERNAL_MODEL_KEY
api_key_header: Authorization
api_key_scheme: Bearer
headers:
X-Tenant-ID: env:MODEL_TENANT_ID
request_template: |
{"engine": {{ json .Model }}, "prompt": {{ json .Prompt }}}
response_path: result.outputs[0].textSome user configuration is required
SecureAI cannot infer a private API's URL, credentials, model name, or JSON contract. The model owner must provide those values. Keep keys in environment variables and commit only the variable names.
Security defaults
- The proxy listens on
127.0.0.1:8090unless you choose another address. It has no authentication of its own, so keep it on loopback. Binding it somewhere reachable, such as0.0.0.0:8090, lets anyone who can reach the port spend your provider key. - Provider keys are loaded from
api_key_envand are never written to output. - Unknown config fields, missing environment variables, oversized responses, and streaming requests are rejected.
GET /healthzreports the provider type and model without exposing credentials.
Next, put the proxy target in a four-phase lifecycle manifest.