Octelium documentation · Latest
Octelium as an AI Gateway
Overview
Octelium provides a self-hosted, open source infrastructure for building AI gateways to SaaS and self-hosted models. The dedicated LLM Service mode understands inference APIs rather than treating them as generic HTTP traffic. It provides the following:
Secretless access to model providers using bearer tokens, custom API key headers, basic authentication, OAuth2 client credentials or AWS Signature Version 4 (read more here).
Native validation for the OpenAI, Anthropic, Gemini Developer API and Amazon Bedrock Runtime protocols, including streamed responses.
Identity-aware, application-layer access control using normalized operations, routes, models, tools, input modalities and token limits (read more here).
Managed system instructions, message injection, tool filtering and reasoning controls on a per-request basis.
Request and response guardrails for secrets, personal information and custom patterns.
Token-consumption quotas in addition to request-based rate limits.
Semantic caching and semantic model routing using either the current upstream or a separate embedding API.
Inference-specific access logs with provider usage, cache and routing decisions, tool changes, finish reasons and time to first token.
Managed containers for self-hosted OpenAI-compatible model servers (read more here).
GitOps-friendly declarative management (read more here).
Secretless access to AI LLM APIs — no keys to share
Guardrails, semantic caching & DLP via plugins
Create an LLM Gateway
In this guide, we expose an OpenAI provider through public clientless access (read more about the BeyondCorp mode here). First, create a Secret for the upstream provider key:
Now create the Service:
Apply the configuration as follows:
The downstream client authenticates to Octelium. Octelium authenticates separately to the upstream and never exposes the provider key to the client.
The protocol describes both sides of the gateway by default. Octelium validates and normalizes the inference API. It can also translate the generation operation to an upstream that speaks another protocol (read more here). Use a separate Service for each downstream protocol.
Other Providers
An Anthropic gateway uses the native Messages API and an x-api-key credential:
A Gemini Developer API gateway uses the native /v1beta API:
Amazon Bedrock Runtime uses the BEDROCK protocol and signs upstream requests on-the-fly:
OpenAI-compatible providers can use their API base path directly in upstream.url. For example, https://openrouter.ai/api/v1 maps a downstream /v1/chat/completions request to the upstream /api/v1/chat/completions route.
Client Side
Authorized Users can access the Service privately through the octelium client or publicly through the clientless mode. A workload can use an OAuth2 client credential (read more here) to obtain an Octelium access token and pass it to an ordinary provider SDK.
Here is a Typescript example for the OpenAI gateway:
The SDK sends the Octelium token to the Service; the provider receives the credential configured in config.llm.auth.
Access Control
The LLM mode exposes normalized request fields under ctx.request.llm. This keeps Policies independent from provider-specific JSON shapes. The following Policy allows members of ai-users to make generation requests against an approved model, with an explicit output maximum and without image input or tools:
You can also authorize by exact route, streaming mode, tool names, input count, audio input and the underlying HTTP request. Read more about every available field here.
Control Prompts, Tools and Reasoning
Inference-specific plugins let the gateway control what reaches the model without maintaining provider-specific Lua scripts. The following configuration owns the system instruction, only allows read-only functions and caps reasoning at a portable level:
REJECT refuses a downstream request that tries to provide its own system instructions. Other prompt modes can prepend, append, replace or strip those instructions, and message plugins can insert or edit selected user and assistant messages.
Tool filters can match function names or provider-hosted tool types, and can allow, remove, deny or replace their definitions. Provider-hosted tools and provider-invoked remote MCP servers execute inside the provider, so allow their types explicitly when they are required.
Reasoning can also use an exact tokenBudget, a provider-native effort, or a CEL/OPA result. A conditional reasoning plugin can override the default for selected identities or requests.
Guardrails
Guardrail plugins inspect semantic parts of inference content rather than raw JSON paths. The following example blocks detected credentials and redacts email addresses before the prompt leaves the gateway:
Patterns can use RE2 regular expressions, personal-information detectors or the built-in secret detector. Request matches can be denied, redacted, stripped or replaced. A response guardrail can inspect model output, but it buffers a streamed response until generation completes and can only deny it. Read more here.
Token Quotas
Request rate limiting alone does not bound model usage because one request can consume far more tokens than another. A token rate limit reserves estimated input and maximum output capacity before calling the provider, then reconciles it with provider-reported usage:
The scope can count total, input or output tokens. The key can be per User, per Session or computed with CEL. Multiple matching token limits are all enforced, which lets a Service combine per-user and per-tenant quotas. A regular request rateLimit plugin can be added to prevent high-frequency loops.
Semantic Caching
Semantic caching reuses a successful earlier completion when a new request has the same meaning and exact execution context. This avoids an inference request entirely and therefore consumes no inference tokens.
The default cache partition is per User. A per-session, shared or CEL-derived tenant partition can be used instead. Shared caching crosses identity boundaries and must only be used when every authorized caller is entitled to every cached answer. Responses containing tool calls are never cached, and cached responses still pass response guardrails.
The current upstream can generate embeddings for OPENAI and GEMINI Services. An ANTHROPIC or BEDROCK Service, or a Service whose model provider does not expose embeddings, can configure a separate embedding upstream and credential. Read more here.
Semantic Routing
Semantic routing lets clients request a logical model such as auto while Octelium chooses a model from the meaning of the request:
Each description and example is embedded independently. The highest-scoring route above its threshold selects the model; otherwise the fallback is used. The original client-requested model remains in ctx.request.llm.model for authorization and auditing. Read more here.
Dynamic Provider Routing
Dynamic configuration can route requests to another compatible provider account or upstream based on identity and normalized LLM context (read more here):
Every dynamic upstream must speak the protocol configured globally on the Service. Semantic routing chooses a model within that protocol, while dynamic configuration can additionally select its compatible upstream and credential.
Self-Hosted Models
An OpenAI-compatible server can run behind NAT, be served by a connected User, or be deployed as a managed container. Here is a minimal managed-container example:
The container must listen on 0.0.0.0. Commands, arguments, environment variables, persistent volumes, registry credentials, probes and replica counts are described here.
Visibility
LLM access logs include the authenticated identity, HTTP request, normalized protocol, operation, route, requested and served model, streaming state, provider usage, reasoning, tool changes, finish reason, time to first token, token quota outcome and semantic cache or routing decision (read more here).
Prompt and completion bodies are not recorded by default. They can be enabled under config.llm.visibility, but doing so can store secrets, personal information, source code and proprietary data in the audit backend. Semantic caching stores prompt-derived vectors and generated responses for the configured TTL independently of access-log body visibility.
Read the complete LLM mode reference here.