CoreLayer AI Security logoCoreLayer AI Security

Model proxy

Expose an OpenAI, Anthropic, Gemini, Ollama, or custom text model through one local Chat Completions endpoint that SecureAI can test.

Terminal
secureai proxy --config secureai.provider.yaml

Why 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

secureai.provider.yaml
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: 1024
Terminal
export 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-model

Provider presets

TypeUpstream APIAuthentication default
openaiOpenAI Chat Completions compatible JSONAuthorization: Bearer
anthropicAnthropic Messagesx-api-key
geminiGemini generateContentx-goog-api-key
ollamaOllama chat with streaming disabledNo 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.

secureai.provider.yaml
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].text

Some 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:8090 unless you choose another address. It has no authentication of its own, so keep it on loopback. Binding it somewhere reachable, such as 0.0.0.0:8090, lets anyone who can reach the port spend your provider key.
  • Provider keys are loaded from api_key_env and are never written to output.
  • Unknown config fields, missing environment variables, oversized responses, and streaming requests are rejected.
  • GET /healthz reports the provider type and model without exposing credentials.

Next, put the proxy target in a four-phase lifecycle manifest.