Octelium documentation · Latest
Self-Hosted Remote Ollama
Octelium enables you to seamlessly provide secure access to Ollama via both the private client-based mode over WireGuard/QUIC as well as the public clientless secure access (read more about the clientless BeyondCorp access mode here) for lightweight open models such as Google's Gemma 3, DeepSeek R1, Meta's Llama, Qwen, etc....
Ollama is served via the dedicated LLM Service mode (read more here), which understands the inference API rather than treating it as generic HTTP traffic. This enables you to apply to your self-hosted models the very same identity-aware access control by model and token limits, token quotas, guardrails, managed prompts and inference-specific visibility that you apply to SaaS providers (read more about using Octelium as an AI gateway here).
Deploy Ollama
Here is a simple example where you can seamlessly deploy an Ollama server as a managed container and serve it as an Octelium Service (read more about managed containers here):
Ollama serves the OpenAI-compatible API over the canonical /v1 routes (read more here), so we use the OPENAI protocol. The LLM mode only exposes the inference routes of the protocol (read more here) and rejects everything else before it reaches the upstream, including Ollama's native model management API (e.g. /api/pull and /api/delete). That's why the container pulls the model itself upon startup.
The above configuration is simply a CPU-only mode. If your underlying Kubernetes installation supports requesting and scheduling GPUs (read more here), you can modify the above configuration to be as follows:
The models are stored by default at /root/.ollama inside the container. You might want to mount a persistent volume at that path (read more about volumes here) or explicitly set the OLLAMA_MODELS environment variable (read more here) to a path mounted via a persistent volume in order to avoid having to pull the models again whenever the container restarts.
You can now apply the creation of the Service as follows (read more here):
You can also serve an Ollama server that's served by a connected User (read more here), for example from a GPU-equipped machine behind NAT, as follows:
Client-Based Access
Once connected to the Cluster (read more about connecting to the Cluster here), you can access the Ollama OpenAI-compatible API at the base URL http://ollama:11434/v1 via any OpenAI-compatible client, SDK, coding agent or chat UI. For example, you can use curl as follows:
The ollama CLI (e.g. ollama run and ollama pull) uses Ollama's native API rather than the OpenAI-compatible API. Therefore, it cannot be used with an LLM Service. If you really need the native API, you can still expose Ollama via an ordinary HTTP Service (read more here), at the cost of losing all the inference-aware features of the LLM mode.
Clientless Access
You can also access Ollama via the clientless BeyondCorp mode from within your applications written in any programming language without having to use the octelium client or any special SDK. For example, you can use the OAuth2 client credentials flow (read more here) to obtain an Octelium access token and use it as the API key of the ordinary OpenAI SDK as in the following Python code example:
The OpenAI SDK sends the Octelium access token to the Service while Ollama itself never needs to be exposed or to be aware of the Cluster at all. Read more about using OAuth2 client credentials in other programming languages here.
Alternatively to the OAuth2 client credentials flow Credential, you can also generate an access token Credential and use it directly as a bearer token. Read more here.
Regarding authentication for HUMAN Users (read more here), you can seamlessly authenticate to the Cluster via your web browser using an IdentityProvider (read more here). There are currently 3 types:
GitHub OAuth IdentityProvider as shown in detail here
OpenID Connect IdentityProviders (e.g. Okta, Auth0, etc...) as shown here.
SAML 2.0 IdentityProviders (e.g. Okta, Entra ID, etc...) as shown here.
Furthermore, you can register a FIDO2 Authenticator (e.g. Yubikeys) in order to directly login later via Passkey (read more here) without having to use an IdentityProvider.
Access Control
The LLM mode exposes the normalized inference request information under ctx.request.llm to your Policies (read more here). For example, the following Policy only allows members of the ai-users group to generate output using the gemma3:1b model with an explicit output maximum:
Token Quotas
The GPU time of your self-hosted models is typically the scarcest resource. Instead of only limiting the request count, you can limit the tokens consumed by every User (read more here) as follows:
Semantic Caching
Ollama also serves embedding models over the OpenAI-compatible /v1/embeddings route. Therefore, you can enable semantic caching (read more here) using the same Ollama server as the embedding backend and keep your entire inference stack self-hosted. You only need to additionally pull an embedding model such as nomic-embed-text in the container:
A cache hit avoids an inference request entirely and therefore consumes no GPU time and no token quota.
Visibility
Octelium also provides OpenTelemetry-ready, inference-aware visibility and access logging in real time that includes the authenticated identity, the operation, the requested and served model, the provider-reported token usage, the finish reason and the time to first token (read more here). You can read more about visibility here.
Here are a few more features that you might be interested in:
Managed system instructions, message injection, tool filtering and reasoning controls (read more here).
Request and response guardrails for secrets, personal information and custom patterns (read more here).
Semantic routing between different models according to the meaning of the request (read more here).
Dynamic routing to different upstreams and models according to identity and request context (read more here).
Exposing the API publicly for anonymous access (read more here).