Overview
The LLM mode turns an Octelium Service into an identity-aware LLM gateway. It validates inference API requests, makes normalized LLM information available to Policies and dynamic configuration, injects upstream credentials and records inference-specific access logs. It also provides inference-aware plugins for prompts, tools, guardrails, model selection, reasoning, token rate limiting, semantic caching and semantic routing.
Here is a simple OpenAI gateway:
The isPublic field enables public clientless access to the Service (read more here). An authorized workload can use the Service URL as the base URL of an ordinary OpenAI client and use its Octelium access token instead of the provider API key.
Protocols
The protocol field describes the inference API spoken by both downstream clients and the upstream. It defaults to OPENAI. Octelium validates and normalizes the following protocols:
OPENAIsupportsPOST /v1/chat/completions,POST /v1/responses,POST /v1/completions,POST /v1/embeddings,POST /v1/moderations,GET /v1/modelsandGET /v1/models/{model}.ANTHROPICsupportsPOST /v1/messages,POST /v1/messages/count_tokens,GET /v1/modelsandGET /v1/models/{model}.GEMINIsupports content generation, streaming content generation, token counting and single or batch embeddings over the Gemini Developer API/v1betaroutes.BEDROCKsupports the Amazon Bedrock Runtime Converse and InvokeModel routes. Converse has normalized inference semantics. InvokeModel carries a model-native body, so it is proxied as raw inference without body parsing or inference-specific plugin processing.
Body-carrying operations require an application/json media type and a JSON object. Unsupported paths, methods and streaming combinations are rejected before reaching the upstream.
The LLM mode does not translate between protocols. The downstream and upstream of a Service must speak the same protocol. OpenAI-compatible servers such as vLLM and Ollama are supported when they expose the canonical routes. Azure OpenAI deployment routes and Vertex AI project-scoped routes are not the OPENAI and GEMINI protocols described here.
Operations and Routes
ctx.request.llm.operation describes what a request does independently of the provider protocol:
GENERATEgenerates output from an input.EMBEDgenerates vector embeddings.MODERATEclassifies an input for safety.COUNT_TOKENScounts input tokens without generating output.LIST_MODELSandGET_MODELdiscover models.RAW_INFERENCErepresents a model-native Bedrock InvokeModel request whose body Octelium does not parse.
ctx.request.llm.route retains the exact API surface. Its values are CHAT_COMPLETIONS, RESPONSES, COMPLETIONS, EMBEDDINGS, MODERATIONS, MODELS_LIST, MODELS_GET, MESSAGES, COUNT_TOKENS, GENERATE_CONTENT, EMBED_CONTENT, CONVERSE and INVOKE_MODEL.
Use the operation in rules that should work across protocols and the route when the exact API shape matters.
Upstream Base Paths
The path in upstream.url acts as the provider base path. For OPENAI, ANTHROPIC and GEMINI, Octelium removes the leading version segment from the canonical downstream route and appends the remainder to that base path. The following example forwards /v1/chat/completions to /api/v1/chat/completions:
When upstream.url has no path, the canonical downstream path is preserved. BEDROCK has no version prefix and appends its route as is. The path configuration or a path plugin can handle providers with another layout.
Secretless Access
The auth field supports bearer tokens, custom API key headers, basic authentication, OAuth2 client credentials and AWS Signature Version 4 (read more here). The credential used to access the Octelium Service is independent from the provider credential. Downstream credentials are never forwarded to the provider.
Custom API Key
Anthropic uses an API key in x-api-key and requires a version header:
Gemini can use the same authentication type with header: x-goog-api-key.
OAuth2 Client Credentials
Basic Authentication
AWS Signature Version 4
Model Selection
By default, the model requested by the downstream is preserved. model can replace it with a static value, a CEL result or a Rego result.
Static Model
CEL
The CEL expression must return a string. An empty string preserves the downstream model.
Open Policy Agent
The Rego script must produce a string through result. An empty result preserves the requested model. The normalized ctx.request.llm.model field always contains the downstream-requested value, even when the upstream model is replaced. Conditional model selection is also available as a plugin.
Reasoning
The reasoning field makes the Service, rather than the downstream, decide how much a reasoning model is allowed to think. It overwrites the downstream configuration for operations that support reasoning and is a no-op for other operations.
Portable Level
The portable levels are NONE, MINIMAL, LOW, MEDIUM, HIGH, XHIGH and MAX. Octelium selects the strongest model-supported configuration that does not exceed the configured level. It never resolves upwards or silently drops an incompatible restriction.
Token Budget
tokenBudget is exact and only works with models that accept numeric reasoning budgets. A model that only accepts ordinal effort is rejected. Zero is invalid; use level: NONE to disable reasoning.
Provider-Native Effort
effort is passed as an ordinal provider-native value. It is the escape hatch for an effort not represented by a portable level and is not translated to a numeric budget.
CEL
The expression returns a portable level such as HIGH, a numeric budget such as 4096, or a provider-native effort. An empty result preserves the downstream reasoning configuration.
Open Policy Agent
Conditional reasoning configuration is also available as a plugin. The last matching reasoning plugin overwrites this default.
Embeddings
Semantic caching and routing require an embedding configuration. Define it once in llm.embedding, or override it within an individual semantic plugin.
The current upstream can generate embeddings for OPENAI and GEMINI Services:
Use a separate OPENAI or GEMINI embedding API when the main upstream does not provide compatible embeddings:
Zero dimensions uses the model default. Changing the model or dimensions makes vectors stored with the previous configuration unreachable. The embedding backend receives prompt-derived content after request guardrails have run.
Limits
maxRequestBytesbounds the JSON request body buffered and parsed by Octelium.maxStreamEventBytesbounds inspection of an individual streamed event. A larger event is forwarded but not inspected.maxEstimatedInputTokensrejects a request above Octelium's byte-based pre-flight estimate.maxOutputTokensrejects a downstream-declared output maximum above the value. It does not insert a limit when the request declares none.maxToolsbounds the number of declared tools.maxToolSchemaBytesbounds the serialized JSON Schema of one tool.
Zero uses an Octelium default or disables an optional inference limit, depending on the field. Internal hard limits always apply. The input estimate is not provider-accurate and must not be used for billing; read ctx.request.llm.estimateQuality alongside it.
Access Control
LLM-specific request information is stored in ctx.request.llm. The underlying HTTP request and parsed body are available in ctx.request.llm.http and ctx.request.llm.http.bodyMap (read more about HTTP access control here).
The normalized fields are:
protocol,operation,route,modelandstream.estimatedInputTokens,estimateQualityandmaxOutputTokens.hasTools,toolCountand the boundedtoolNameslist.inputItemCount,hasImageInputandhasAudioInput.
The values describe the request sent by the downstream before model, prompt or reasoning plugins mutate it. Prefer them over inspecting an untrusted, deeply nested body whenever possible.
Dynamic Configuration
Dynamic configuration can select compatible upstreams, credentials and configuration from identity and normalized LLM context (read more here):
protocol and limits are global and only take effect in the default configuration. listenHTTP2 and cors are also global. Every selected upstream must speak the global protocol because Octelium does not translate protocols.
HTTP Configuration
Since LLM is HTTP-based, config.llm also supports header and path manipulation, HTTP/2 and CORS (read more here):
Header and path changes apply after the downstream operation is validated. The host can instead be preserved or computed with eval, and forwardedMode can be DROP, OBFUSCATE or TRANSPARENT. isUpstreamHTTP2 affects connections to the provider. listenHTTP2 and cors are global because they affect downstream connections and unauthenticated preflight requests. Enabling cors.allowClusterServices trusts browser applications served by every Service in the Cluster.
Continue with the LLM plugins and LLM visibility references.