LLM Proxies: Purpose and Security Policy
6 min read
Overview
Unique provides three authenticated passthrough proxies for clients and internal agent workflows that need provider-compatible APIs:
OpenAI proxy for OpenAI-compatible APIs: Chat Completions, Responses, model listing, image edits and Code Interpreter containers, including streaming, uploads, and binary responses.
Anthropic proxy for Anthropic-compatible Messages API requests, including regular and SSE streaming responses.
Cursor proxy for the subset of the Cursor API used by the Cursor SDK agent lifecycle.
These proxies let callers use provider-native request and response formats while Unique manages upstream credentials, model routing, usage attribution, limits, and security controls. Routes and request capabilities are checked before forwarding.
Provider-hosted tools deserve special attention because they execute under credentials held by Unique and may send prompts, files, or tool arguments to infrastructure outside Unique-controlled environments. The proxy policies therefore use explicit allowlists for tool capabilities and reject unknown typed tools by default.
Public endpoints and service location
Clients call the proxies below the Public API base path:
/public/chat/openai-proxy/{provider-path}/public/chat/anthropic-proxy/{provider-path}/public/chat/cursor-proxy/{provider-path}
All three proxies replace or supply the upstream authorization credential. Callers authenticate to Unique; provider credentials are kept in the backend.
OpenAI proxy
Purpose and routing
The OpenAI proxy exposes an OpenAI-compatible path surface. The requested model is resolved through Unique's OpenAI service factory, which selects the configured Azure OpenAI or LiteLLM-backed route. It supports normal JSON requests, SSE streaming, multipart uploads, and binary downloads.
Common examples include:
POST /v1/chat/completionsPOST /v1/responsesGET /v1/modelsCode Interpreter container operations and
POST /v1/images/edits
OpenAI path checks normalize query strings, repeated slashes, trailing slashes, and encoded path segments before applying the security policy. Equivalent aliases such as /responses and /chat/completions receive the same checks as their /v1/... forms.
Tool and parameter policy (as of release .38)
For Chat Completions routes:
Allowed tool types:
function,custom.Blocked parameter:
web_search_options.namespacetools are rejected on Chat Completions; they are a Responses API construct.The checks apply to both the top-level body and
extra_body; thereforeextra_body.toolsandextra_body.web_search_optionscannot bypass the policy.
For Responses and other OpenAI routes carrying tool declarations:
Allowed tool types:
function,custom,apply_patch,local_shell, andcode_interpreter.shellis allowed only whenenvironment.typeislocal.namespaceis allowed as a grouping wrapper only (Codex CLI 0.147 and later send their client-executed function tools this way). The namespace itself executes nothing. It must carry atoolsarray, and every nested tool is validated against the same client-executed allowlist as a top-level tool: hosted tools, hostedshellenvironments, and further nestednamespacetools inside a namespace are rejected.All other typed tools are rejected by default.
This blocks provider-hosted capabilities, whether declared at the top level, under extra_body.tools, or nested inside a namespace, such as:
mcpweb_searchweb_search_preview, except Unique internal Deep Research when OpenAI is the research enginefile_searchimage_generationandimage_generatorcomputerandcomputer_use_previewHosted
shellenvironments
code_interpreter and OpenAI container routes remain available by design for approved code-execution workflows. Allowing container routes does not allow blocked tool declarations to bypass body validation.
The integrated /integrated/chat/stream-responses flow applies the same Responses tool policy to its options before calling the upstream model.
Anthropic proxy
Purpose and routing
The Anthropic proxy accepts Anthropic-compatible requests and forwards them through the company-scoped LiteLLM route. It supports regular Messages responses and SSE streaming while preserving company-level usage and cost attribution.
Common examples include:
POST /v1/messagesPOST /v1/messages/count_tokens
Tool and parameter policy (as of release .38)
Allowed capabilities:
Untyped custom tool definitions
Tool type
customTool type
functionTool types beginning with
code_execution
Blocked capabilities:
mcp_servers, both top-level and underextra_bodyTyped web search and web fetch tools
Typed MCP tools
Advisor and tool-search tools
Browser and computer tools
Bash and text-editor tools
Memory tools
Any other unknown typed tool
Tool declarations are checked in both tools and extra_body.tools. Anthropic code_execution* remains enabled by design for approved code-execution workflows.
Cursor proxy
Purpose and routing
The Cursor proxy supports the API surface required by the Cursor SDK to create, run, resume, and dispose agents. Requests are forwarded directly to configured Cursor upstreams with the platform-held Cursor credential:
Primary API:
CURSOR_API_BASE_URL, defaulting to<https://api.cursor.com>Authentication API:
CURSOR_AUTH_API_BASE_URL, defaulting to<https://api2.cursor.sh>
Regular responses and Cursor's NDJSON streaming responses are supported.
Allowed routes
Cursor uses a route-and-method allowlist, like the OpenAI and Anthropic proxies. Unlike them, it cannot be extended per environment. Only these routes and methods are forwarded:
/v1/agentsand descendant agent lifecycle routes:GET,POST,PATCH,DELETE/v1/models:GET/v1/me:GETExact route
/auth/exchange_user_api_key:POST
Every other Cursor route or method is blocked. Cursor does not currently apply an OpenAI/Anthropic-style body tool filter; its security boundary is the narrow route-and-method allowlist required by the SDK.
Route security
OpenAI and Anthropic allowed routes (as of release .42)
The OpenAI and Anthropic proxies forward only the method-and-path pairs below. Paths are relative to the proxy mount. * matches exactly one path segment, such as a container or file ID.
OpenAI (each route also accepted with a /v1 prefix):
POST /chat/completionsPOST /responsesPOST /containersGET /containers/*GET,POST /containers/*/filesGET /containers/*/files/*/contentPOST /images/editsGET /v1/models(only with the/v1prefix)
Anthropic:
POST /v1/messagesPOST /v1/messages/count_tokens
Every other method or path is rejected with 403 before any upstream call. This includes the root proxy path, LiteLLM management routes (keys, spend, teams, users, organizations, settings), files, batches, assistants, vector stores, RAG ingest, MCP server registration, agents, and provider passthrough routes.
The allowlist applies at every entry point: the node-chat Public API routes, the node-chat internal routes, and the unique-api facades.
Before matching, paths are normalized:
the query string is ignored
the path is URL-decoded up to three times; deeper or malformed encoding is rejected with
400repeated slashes are collapsed and a trailing slash is removed
paths containing
.or..segments are rejected
Extending the allowlist per environment
Operators can add inference routes without a new image:
OPENAI_PROXY_EXTRA_ALLOWED_ROUTESANTHROPIC_PROXY_EXTRA_ALLOWED_ROUTES
Rules:
Format: comma-separated
METHOD /pathentries, e.g.POST /images/generations,POST /v1/embeddings.*matches one path segment.Allowed methods:
GET,POST,PUT,PATCH,DELETE.Paths exclude the proxy mount:
/v1/messages/batches, not/anthropic-proxy/v1/messages/batches.Set the same value on
backend-service-chatandunique-api. A route allowed on only one service is still blocked on the other entry points.Entries only add routes; they never remove built-in ones.
Entries whose first segment (after an optional
v1) is a known LiteLLM management or provider passthrough root are rejected, for examplekey,spend,team,user,admin,vector_stores,rag,mcp,agents,openai,anthropic,azure,bedrock,gemini. The list is not exhaustive: only add inference routes.An invalid or forbidden entry stops the service from starting. Kubernetes keeps the previous pods serving.
Cursor denied routes
For Cursor, every route not present in the allowlist above is denied. This prevents a caller from using Unique's Cursor credential against billing, account-management, administrative, or future Cursor APIs that have not been explicitly reviewed.
Rejection behavior
Security checks run before the upstream request is sent.
A route outside the allowlist is rejected with HTTP
403and the bodyopenai-proxy: upstream route not allowed(oranthropic-proxy: ...). The service logs an erroropenai-proxy.rejected_route/anthropic-proxy.rejected_routewith user ID, company ID, method, and path.A path with malformed or too deeply nested encoding is rejected with HTTP
400.A malformed or disallowed request capability is rejected as a client error by
node-chat.The
2026-03-01unique-apiOpenAI/Anthropic facades may expose forwarded non-streaming proxy validation failures as HTTP422according to their upstream-error contract.Streaming facades relay upstream status and body where supported.
The policy implementation and tests are the source of truth when provider APIs evolve.