DEV Community

Cover image for Ollama has no authentication: 5 ways to share it with your team safely
Artemy Andruschak
Artemy Andruschak

Posted on AI-assisted

Ollama has no authentication: 5 ways to share it with your team safely

Ollama has no API keys. It listens on 127.0.0.1:11434 and answers whoever connects. On a laptop that's fine. The trouble starts when someone sets OLLAMA_HOST=0.0.0.0 so a colleague can use the GPU box under the desk, and from then on every endpoint is open to anyone who can reach it. Not only chat, but also pull, delete, create and push.

A few numbers from this year:

  • In January, SentinelOne and Censys counted about 175,000 Ollama servers open to the internet in 130 countries. 48% of them had models with tool calling.
  • In May, Cyera published Bleeding Llama (CVE-2026-7482). Two unauthenticated requests, /api/create with a crafted GGUF file and then /api/push to the attacker's registry, leak the server's memory: environment variables, API keys, other people's prompts. The fix shipped in 0.17.1 back in February, but the release notes didn't call it a security fix, so plenty of servers never got updated.

Don't wait for keys in Ollama itself. In 2025 a maintainer wrote under a PR that added them: "In the short-term we don't plan to add an API key system to the Ollama server itself. Usually I recommend using a VPN like tailscale." As of 0.40.3 (October 2026) there is still no server-side setting for it. There is an OLLAMA_AUTH variable, but it only makes the ollama client sign the requests it sends.

So the protection has to sit in front of Ollama. Here are five ways to do that, from the simplest to the most complete, and what each one leaves open.

First, check that yours isn't open

From a machine outside your network:

curl -s --max-time 5 http://YOUR_PUBLIC_IP:11434/api/tags
Enter fullscreen mode Exit fullscreen mode

If that prints a list of models, anyone can use them. Also run ollama -v: anything older than 0.17.1 needs an update whatever else you decide.

If Ollama runs in Docker, look at how the port is published. -p 11434:11434 listens on every interface, and Docker writes its own iptables rules, so a ufw rule that denies 11434 doesn't block it. Use -p 127.0.0.1:11434:11434, or don't publish the port at all when only other containers need it.

1. Keep it on localhost and use SSH or Tailscale

The least work: Ollama stays private and people come in over a channel that already has authentication.

For one or two people, an SSH tunnel is enough:

ssh -N -L 11434:localhost:11434 you@gpu-box
Enter fullscreen mode Exit fullscreen mode

Clients then use http://localhost:11434 as if Ollama ran on their own machine.

For a team, Tailscale is the usual answer, and it's what the Ollama maintainer suggested. Let Ollama listen on all interfaces (sudo systemctl edit ollama):

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Enter fullscreen mode Exit fullscreen mode

and let the firewall accept the port only from the tailnet:

sudo ufw allow in on tailscale0 to any port 11434 proto tcp
Enter fullscreen mode Exit fullscreen mode

With ufw on and its default of denying incoming traffic, nothing else gets through. Tailscale ACLs then decide which people or devices can reach the box at all.

What it leaves open: anyone who gets in can use the whole API, including deleting models. Every request looks the same to Ollama, so you can't tell who is using the GPU or how much, and you can't take access away from one script without taking it from the person who runs it. Every user also has to install and sign in to Tailscale, and tools running in the cloud, like a hosted n8n, can't easily join.

2. A reverse proxy that checks a token

If clients need a normal HTTPS address, put a proxy in front that refuses requests without a token. With Caddy, which gets the certificate by itself:

ollama.example.com {
    @no_token not header Authorization "Bearer {$OLLAMA_TOKEN}"
    respond @no_token 401

    # Nobody outside needs to create, push or delete models
    @model_admin {
        path /api/create /api/push /api/pull
        path /api/delete /api/copy /api/blobs/*
    }
    respond @model_admin 403

    reverse_proxy localhost:11434 {
        header_up Host {upstream_hostport}
    }
}
Enter fullscreen mode Exit fullscreen mode

Start Caddy with a long random OLLAMA_TOKEN in its environment. Ollama itself stays on 127.0.0.1. The Host line matters: Ollama listening on localhost refuses requests addressed to any other host name, which is why the Ollama FAQ sets Host localhost:11434 in its nginx example. Without that line, Ollama answers 403 to any request that comes in under a real domain name. Streaming works as is.

OpenAI-compatible clients (Continue, Cursor, n8n, the OpenAI SDKs) take the token as their API key with https://ollama.example.com/v1 as the base URL.

Closing the model management endpoints is worth doing even with a token: they are the ones Bleeding Llama needed.

What it leaves open: one token for everyone. When someone leaves, you change it on every machine. You still can't see who sent what. You can give each person their own token with a map in nginx or several matchers in Caddy, but then you are writing your own small gateway in a config file.

3. Open WebUI as the front door

If your team already chats through Open WebUI, it can be the only way in. Ollama stays private, everyone gets an Open WebUI account (or signs in through your SSO), and people who need the API create personal keys.

An admin turns keys on under Admin Settings → Authentication → API Keys, non-admins also need the API Keys permission, and then each person creates a key in Settings → Account. According to the docs, a key works with the same endpoints as the web interface: OpenAI-style /api/chat/completions, and /ollama/api/* passed through to Ollama.

What it leaves open: a key gets all the rights of the person who created it. Endpoint restrictions exist, but they apply to every key on the instance, not to one. The docs don't mention spending or rate limits per key, so an agent stuck in a loop can hold the GPU all day.

4. A proxy built for this: LoLLMs Hub or LiteLLM

Two existing projects give each person a key without a hand-written config.

LoLLMs Hub by ParisNeo (it started as ollama_proxy_server, and the Ollama README lists it as "Ollama Fortress") puts keys, rate limits and per-user usage stats in front of one or many Ollama servers, spreads load across several GPU machines, and lets you pull and delete models from its admin page. Apache-2.0. Pick it if you have more than one box.

LiteLLM proxy gives each person a virtual key with a budget and a rate limit, and it talks to Ollama and to about a hundred cloud providers. Virtual keys need a Postgres database next to it, and it has a lot of settings. Pick it if someone on the team will look after it.

What they leave open: one more service to run and update. That's true of options 2 and 3 as well, but these are bigger.

5. Spillway (I built this one)

Full disclosure: I wrote Spillway, so take this section with that in mind.

I built it for a 10–50 person company that has Ollama on one GPU box, also pays for Claude or OpenAI, and has nobody whose job is to run infrastructure. It's free and open source, single sign-on included, and nothing in it is held back for a paid plan. One container with SQLite and an admin page:

mkdir spillway && cd spillway
curl -fsSLO https://raw.githubusercontent.com/Artemy-And/spillway/main/docker-compose.yml
echo "OLLAMA_URL=http://ollama:11434" >> .env
docker compose --profile ollama up -d
docker compose logs spillway    # prints the setup link
Enter fullscreen mode Exit fullscreen mode

The Ollama container in that compose file publishes no port, so only Spillway can reach it. Spillway answers in Ollama's own format (/api/chat, /api/generate, /api/embed, /api/tags), as well as OpenAI's and Anthropic's, so Open WebUI, Claude Code, Codex and n8n connect with a key, without changes on their side. It doesn't forward /api/create, /api/push or /api/delete at all.

Every person, laptop or n8n workflow gets its own key with a daily and a monthly limit in dollars, which matter once cloud models sit behind the same key. For the GPU itself there's a rule that caps agent keys at so many requests per minute. The request log shows who sent what, with card numbers and similar personal data masked, and another rule blocks prompts with such data from cloud models while local ones still answer. When a team runs out of its cloud budget or a provider goes down, requests go to the local model instead of failing.

What it leaves open: it's young (version 0.4) and I'm the only maintainer. It's AGPL-3.0, which some companies don't allow. It doesn't spread load across several GPU machines. And if two people just share one GPU, it's more than you need: use option 1.

Which one to pick

Access per person Limits per key Setup
SSH / Tailscale per device, in Tailscale no minutes
Proxy with a token one shared token no an hour
Open WebUI keys yes no minutes, if you already run it
LoLLMs Hub yes rate an evening
LiteLLM yes budget and rate an evening, plus Postgres
Spillway yes dollars, and rate for agents minutes

A rule of thumb: two or three people who trust each other, Tailscale. People and scripts that need an HTTPS address, a proxy with the model management endpoints closed. More people than you can track in your head, or a mix of local and cloud models, something with a key per person.

Whatever you choose, run Ollama 0.17.1 or later and make sure port 11434 doesn't answer from the internet. If you've got Ollama shared in another way that works well, I'd like to hear about it in the comments.

Top comments (0)