Yes. An LLM gateway is a security risk because it concentrates every provider key, every prompt and every log line in one service, which makes it one of the most valuable targets in your stack. You can still run one safely: keep it off the internet, restrict its egress, pin and verify every release, issue scoped keys, and never log secrets.
On 21 October 2026, LiteLLM's release pipeline published a poisoned 1.107.0 to PyPI and its Docker tags, the project's second supply chain compromise this year. We covered the incident in our LiteLLM 1.107.0 write-up. This post answers the architecture question: should you run a gateway at all, and if so, how do you stop it leaking every key you own? The advice applies to any self-hosted gateway. LiteLLM is the example because its maintainers publish detailed incident notes.
Key takeaways
- A gateway is a key vault, a prompt archive and an egress point in one process. Run it like a secrets manager, not a convenience library.
- The documented 2026 gateway failures came from a hijacked release pipeline, logs that captured credentials, a management route reachable by untrusted clients, and attackers hunting exposed AI endpoints.
- You may not need one. For one provider and a few services, provider SDKs with per project keys and spend limits expose less.
- If you run one: private network, egress only to your providers, metadata service blocked, admin UI never public.
- Give every application a scoped virtual key with a budget, model allowlist and expiry. Keep provider keys in a vault, per environment, with provider spend limits as a backstop.
- Turn off content logging. Never log authorization headers, tool outputs or raw requests.
- Pin by version plus hash for Python and by digest for containers. A valid signature did not help on 21 October, because the attacker drove the real pipeline.
Why does an LLM gateway concentrate risk?
A gateway exists to centralise: every application talks to one endpoint while the gateway handles routing, fallbacks, budgets, caching and logging. That same design puts everything sensitive about your AI usage in one place. Here is what a typical self-hosted gateway holds:
| What it holds | Where it usually lives | What an attacker gets |
|---|---|---|
| Upstream provider API keys | Environment variables, a config file, or the gateway's database | Billable access to every model you pay for, often across several providers |
| A master or admin key | Environment variable | The ability to mint new keys, change budgets and read spend data |
| Virtual keys for teams and apps | The gateway database | Impersonation of any team, and a way to hide abuse inside normal traffic |
| Prompts and completions | Spend logs, traces, observability backends | Customer data, internal documents pasted into prompts, source code, and any secret a user or agent pasted |
| Tool call inputs and outputs | The same logs, when agents route through the gateway | Command output, file contents and tokens that tools printed |
| Database connection string | Environment variable | Direct access to keys and logs, bypassing the gateway's own access checks |
| Cloud instance role | The host or pod identity | Whatever that role can do in your cloud account |
LiteLLM's 21 October guidance lists most of these as things to rotate: the instance or task role, every provider key in the proxy database, master and virtual keys, the DATABASE_URL password and any secret in the process environment. That is a gateway's blast radius, described by the people who build one.
Two more things raise the stakes. A gateway makes outbound HTTPS calls with large, varied payloads by design, which is exactly the traffic a credential stealer wants to hide in. And attackers are looking. Infosecurity Magazine reports that Symantec's Threat Hunter Team captured an autonomous attack agent, through an AI honeypot that logged more than 127,000 external requests, which hunts exposed LLM endpoints, self-hosted models, AI gateways and MCP servers so it can run on someone else's paid compute.
What went wrong in 2026's gateway incidents?
In general terms, the documented 2026 problems with one popular gateway fall into four categories, each mapped to a control later in this post.
| Date (2026) | What happened, per the maintainer or reporter | Category | Control that addresses it |
|---|---|---|---|
| 18 March | A custom guardrail that returned the full request object caused plaintext authorization headers to be written to spend logs and OpenTelemetry traces (LiteLLM, fixed in 1.82.3) | Secrets in logs | Logging policy, log access control |
| 24 March | Malicious 1.82.7 and 1.82.8 reached PyPI after, LiteLLM believes, a compromised security scanner in its CI led to its publishing credentials. The official proxy Docker image, which pinned its requirements, was not affected | Release pipeline | Pinning by hash, cooldown, staged rollout |
| 1 June | A crafted Host header could make the proxy treat a protected management route as public, on versions before 1.84.0, when the listener was reachable by untrusted clients (GHSA-4xpc-pv4p-pm3w) | Exposed management surface | Private network, no public admin API |
| 21 October | Three developers' GitHub CLI tokens were used to override branch protection, point the private release workflow at a lookalike repository, pass the approval gate and delete workflow records. Signed 1.107.0 wheels were on PyPI for under two hours, and Docker Hub tags resolved to the bad image for about two and a half | Release pipeline, secrets in logs | Pinning by digest and hash, egress allowlist, credential hygiene |
| 21 October | Symantec reports an attack agent that hunts exposed AI gateways and MCP servers for free compute | Exposed endpoints | Private network, spend alerts |
Two details in the 21 October post matter to anyone running a gateway.
First, how the tokens leaked. LiteLLM is still confirming the path and describes two possibilities: request and response logging that captured a coding assistant's tool call responses containing a developer's GitHub CLI token, or an internal LiteLLM deployment reachable from the public internet, where the team found an unexpected user account and believes the attacker read tokens from its logs. Either way, a gateway's logs held credentials for systems far more important than the gateway, and those logs were reachable.
Second, why signatures did not help. The attacker changed which repository the official workflow built from, so the real pipeline built, signed and published the artifacts through PyPI Trusted Publishing. PyPI's security model documentation says plainly that Trusted Publishing does not protect against a compromised CI workflow or repository. Provenance tells you which pipeline produced an artifact, not who was driving it that morning.
This is not a story about one careless project. After March, LiteLLM had moved releases to a private repository, required approvals, made Docker release tags immutable and signed its images. A gateway sits where a fast open source release cycle meets a pile of high value secrets, and your controls must assume either side can fail.
Do you need a gateway at all?
Many teams adopted a gateway as the quickest way to try several providers, not because production needed one. Providers now expose many controls teams once got only from a gateway. OpenAI's production best practices guide describes separate projects for staging and production, per project rate and spend limits, key expiration, maximum key lifetimes and API key governance. Anthropic's Admin API lets administrators manage workspaces, list API keys with their scope and expiry, and set a key inactive. If those cover your needs, a gateway adds a component without adding much control.
| Your situation | Simplest safe option | Why |
|---|---|---|
| One provider, a handful of services | Provider SDK directly, one project or workspace per service and environment, provider spend limits | No extra component holding keys; the provider's console is your audit trail |
| Several providers, but each app uses only one | Provider SDKs, plus a shared library for retries and timeouts | Routing logic lives in code you already review; no central key store |
| You want one OpenAI compatible endpoint for developer tools | A small internal reverse proxy that injects the key and allows only completion routes | Developers never hold the real key; the proxy has almost no features to attack |
| Many teams, many providers, central budgets and fallbacks | A self-hosted gateway, hardened as described below | You get chargeback and failover, and you accept running a critical service |
| Agents and coding tools on developer machines | An egress proxy that injects credentials, with tools given dummy keys | A compromised tool or dependency on the laptop never sees a real key |
| Regulated data with strict residency | A gateway inside the regulated network, with message logging off and a private model endpoint | Central enforcement of where prompts may go, without central storage of what they said |
The plain OpenAI compatible endpoint came up repeatedly in the Hacker News discussion of the 21 October incident. Commenters described replacing a full router with a small proxy of their own, or giving applications placeholder keys while a proxy outside the process injects the real key for approved hosts only. No database, no admin UI, no plugin system, a small dependency tree: fewer releases to trust.
The trade off is real. A full gateway gives you per team budgets, model aliasing, failover, caching and one switch to turn things off in an emergency. If the alternative is forty services each holding a production key, a well run gateway reduces risk. The real question is whether the features are worth running a high value service, and whether you will run it like one.
How should the gateway be deployed?
Assume the gateway will one day run code you did not intend, through a malicious release, a vulnerable plugin or a management bug. Deployment decides what that code can reach.
Keep it on a private network
The listener should be reachable only from the services that call it. LiteLLM's June advisory says deployments bound to a private network, or behind a gateway requiring its own authentication, were not exposed to the Host header bypass. A management bug you cannot reach is not an emergency. In Kubernetes, use a ClusterIP service rather than a LoadBalancer, with an ingress NetworkPolicy that admits only labelled caller namespaces. On a single Docker host, bind to loopback or an internal network:
services:
llm-gateway:
image: ghcr.io/berriai/litellm@sha256:<digest-you-verified>
ports:
- "127.0.0.1:4000:4000"
read_only: true
user: "10001:10001"
cap_drop: ["ALL"]
security_opt: ["no-new-privileges:true"]
tmpfs:
- /tmp
networks: ["internal"]
networks:
internal:
internal: true
An internal: true network has no route out, so pair it with an egress proxy on a second network.
Never publish the admin UI or management API
Gateways usually serve completion routes and management routes (keys, budgets, users, settings) on the same port. Callers need the first; only administrators need the second, rarely. Put management behind your VPN or identity aware proxy and block it at the ingress for everyone else. LiteLLM's virtual key documentation warns that a key owned by a proxy admin can call admin endpoints unless its allowed_routes restricts it, an easy mistake when an administrator creates keys for others.
Restrict egress to the providers you use
This control most often decides whether a compromise becomes a breach: a stealer that cannot reach its collection server has stolen nothing. Commenters on the 21 October thread said the same. Kubernetes NetworkPolicy works on IP addresses, not hostnames, so allow the gateway pod to reach only DNS, its database and an egress proxy, and enforce a hostname allowlist in the proxy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: llm-gateway-egress
namespace: ai-platform
spec:
podSelector:
matchLabels:
app: llm-gateway
policyTypes: ["Egress"]
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- to:
- podSelector:
matchLabels:
app: egress-proxy
ports:
- protocol: TCP
port: 3128
- to:
- podSelector:
matchLabels:
app: gateway-postgres
ports:
- protocol: TCP
port: 5432
The proxy permits only the provider hostnames you use, such as api.openai.com and api.anthropic.com, and denies and logs everything else. A denied connection from the gateway to an unknown domain is one of the highest signal alerts you can build.
Block the cloud metadata service
LiteLLM advises reviewing CloudTrail for GetCallerIdentity calls from the instance role after 21 October, because harvesting cloud credentials is what stealers do first. A gateway rarely needs a cloud role. On AWS, require IMDSv2 with a hop limit of 1 so containers cannot reach it:
aws ec2 modify-instance-metadata-options \
--instance-id i-0123456789abcdef0 \
--http-tokens required \
--http-put-response-hop-limit 1
The egress policy above already denies 169.254.169.254. If the gateway needs a role to read a secret, scope it to that one secret.
Run as a hardened container
Run as non root, with a read only root filesystem and no added capabilities. That will not stop a stealer reading the process environment, but it stops persistence that survives a restart: the .pth and sitecustomize.py files used in the 2026 LiteLLM payloads need a writable site-packages to be planted after the fact.
How should keys be handled?
There are two layers of keys, and they need different treatment.
Downstream: virtual keys for teams and applications
Callers should never hold a provider key. They should hold a gateway issued key that is scoped, budgeted, rate limited and expiring. In LiteLLM this is a virtual key, which needs a Postgres database and a master key:
curl -sS http://llm-gateway.ai-platform.svc:4000/key/generate \
-H "Authorization: Bearer $GATEWAY_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"key_alias": "search-team-prod",
"team_id": "search",
"user_id": "svc-search-prod",
"models": ["chat-default", "embed-default"],
"max_budget": 200,
"budget_duration": "30d",
"duration": "90d",
"rpm_limit": 120,
"tpm_limit": 200000,
"allowed_routes": ["llm_api_routes"]
}'
Rules that make this layer hold up:
- One key per application and environment, so a leak means revoking one key, not an outage for five teams.
- Model allowlists, so a thief cannot run your most expensive model. Aliases also let you switch providers without reissuing keys.
- Budgets and rate limits on every key. OWASP's LLM10:2025 entry on unbounded consumption names "denial of wallet" as an attack. A key without a budget is an open credit line.
- Expiry and rotation. Set
duration; LiteLLM also documents scheduled rotation withauto_rotateandrotation_interval. - Explicit, non admin ownership. LiteLLM's docs say admins must pass
user_idor the key has no owner, and that management access follows the owner's role. - Central bounds. Cap key parameters so nobody mints an unlimited key, and enforce policy on edits too, since LiteLLM notes its generation hook does not run on updates.
Upstream: provider keys
The gateway needs real provider keys. Keep them few, scoped and replaceable:
- One provider project or workspace per gateway environment. OpenAI recommends separate staging and production projects with their own limits; Anthropic workspaces serve the same purpose.
- Provider spend limits as a backstop. Gateway budgets protect you from your callers; provider limits protect you when the gateway itself is compromised. OpenAI documents spend alerts and a hard monthly limit, and advises reviewing how a hard stop affects production first.
- Expiring keys. OpenAI supports expiry on project keys and a maximum key lifetime; Anthropic's Admin API returns
expires_atper key. Practise rotation before an incident forces it. - Runtime injection from a secret store. Never bake keys into images or config. Better still, have a sidecar or egress proxy add the authorization header so the gateway never sees the raw value.
The dummy key pattern
That last point, taken further, is the pattern several Hacker News commenters described: the application, and even the gateway, hold only a placeholder. An egress proxy recognises the destination host and swaps in the real key from a vault. A stealer inside the application or gateway finds nothing worth sending, and the proxy, with a tiny code base and no plugins, is far easier to keep clean. It becomes your new high value component, so pin and monitor it the same way.
What to rotate first if the gateway is compromised
Following LiteLLM's 21 October guidance, rotate widest access first: the cloud role the host could reach, every upstream provider key, the master key and then all virtual keys, the DATABASE_URL password, then any other secret in the process environment. Then check provider consoles for usage from unfamiliar addresses.
What must never be logged?
Logging is where gateways most often leak secrets that have nothing to do with AI. The 18 March LiteLLM incident put plaintext authorization headers into spend logs and traces. The 21 October incident may have started with GitHub tokens in a gateway's request and response logs. Both times the gateway recorded traffic as designed, and the traffic held things nobody meant to store. OWASP's Logging Cheat Sheet lists data to remove, mask, sanitise, hash or encrypt before recording. For a gateway:
| Never log in clear | Why it shows up in gateway logs | What to do instead |
|---|---|---|
Authorization, x-api-key and similar headers | Raw request logging, custom guardrails or middleware that dump the whole request | Strip at the logging layer; log a key alias or hashed key ID |
| Provider API keys | Debug logging of outbound calls, error messages that echo config | Never enable raw request logging in production |
| Tool call outputs | Agents route tool results back through the gateway as message content | Turn off message logging; if you must keep content, scan and redact before storage |
| Prompt and completion content | Default logging to observability backends | Off by default; opt in per application with a retention period |
| Database connection strings | Startup logs, exception traces | Redact in exception handlers |
| Session tokens and OAuth tokens | Pasted by users into prompts, printed by command line tools | Treat all content as potentially secret; restrict who can read it |
Tool outputs need special emphasis. When a coding agent runs a command, its output returns to the model as conversation content through the gateway. Anything the command printed, tokens included, is now prompt content, and logging prompts logs those tokens. No filter reliably catches every token format in free text, so the safe default is not to store content. LiteLLM's logging page documents these settings:
litellm_settings:
turn_off_message_logging: true # do not send messages or responses to logging callbacks
redact_user_api_key_info: true # drop key hash, user and team IDs from supported loggers
callback_settings:
otel:
message_logging: false # keep message content out of OpenTelemetry spans
Two cautions from the same page: log_raw_request_response puts the raw provider request into log metadata, which you never want in production, and a per request header can override redaction on keys explicitly allowed to opt out, so grant that rarely. Spend tracking still works with content logging off. If a team needs content for evaluation, give it a separate key with logging on, short retention and a named owner.
Protect the logs you keep. OWASP recommends restricting and reviewing read access, recording access to logs and keeping them out of web accessible locations. LiteLLM's March notice says the same in gateway terms: least privilege on spend log views and telemetry backends. An admin UI that shows spend logs is a log viewer and needs the same care.
How do you pin, verify and update the gateway itself?
The 2026 incidents show the release step itself can be hijacked, so your defences must work even when the artifact is signed by the real project.
Pin Python installs by version and hash
Unpinned pip install litellm was the exposed path in March; LiteLLM's official Docker image, which pinned requirements, was not affected. Version pins protect you from new releases, and hashes also protect you if a file at that version is replaced. pip's hash checking mode requires every requirement and dependency to be pinned and hashed once any has a --hash. Generate the file:
# with pip-tools
pip-compile --generate-hashes requirements.in -o requirements.txt
# or with uv
uv pip compile requirements.in --generate-hashes -o requirements.txt
# install, refusing source builds and anything unhashed
pip install --require-hashes --only-binary :all: -r requirements.txt
pip recommends pairing hash checking with --only-binary :all:, because building a source distribution runs arbitrary code. Hashes do not help if you regenerate the file during a bad window; they make sure the version you reviewed is the one you run.
Add a cooldown before adopting new releases
Both 2026 LiteLLM compromises were pulled from PyPI within minutes to a few hours. A short delay before adopting any new gateway release means bad versions are usually gone before you see them. With uv you can resolve as of a past date:
uv pip compile requirements.in --generate-hashes \
--exclude-newer "$(date -u -d '3 days ago' +%Y-%m-%dT%H:%M:%SZ)" \
-o requirements.txt
Commenters on the incident thread noted the trade off: a cooldown also delays security fixes. Keep a reviewed exception path, so that when an advisory like June's authentication bypass lands, a named owner approves the fixed version early.
Pin containers by digest, never by moving tag
On 21 October the latest, main-latest and main-stable tags on Docker Hub and GHCR pointed at the compromised image for a while, per LiteLLM's timeline. Docker's documentation describes pulling by digest as pinning an image that will not change, with the caveat that you get no updates until you change the digest.
# resolve a tag to its digest once, after review
docker buildx imagetools inspect ghcr.io/berriai/litellm:v1.106.2
# then deploy by digest only
docker pull ghcr.io/berriai/litellm@sha256:<digest>
Reference the digest in pod specs and reject tags with an admission policy. An update becomes a reviewable, revertible pull request that changes one digest.
Verify signatures, and know what they prove
LiteLLM signs its Docker images and advises verifying them with cosign using its published key:
cosign verify \
--key <path-or-url-to-the-maintainer-published-public-key> \
ghcr.io/berriai/litellm@sha256:<digest>
Do it, but know what it proves: the image came from the project's signing setup. On 21 October the attacker used that setup. Signatures stop a stranger's lookalike image, not a compromised pipeline, which is why digest pinning, cooldowns and egress limits matter alongside them.
Mirror, stage and watch plugins
Pull releases into your own registry or mirror, run them in staging for a few days, and promote by digest, keeping the previous digest ready for a one line rollback. Treat plugins, custom guardrails and callbacks the same way: each runs with the gateway's access to keys and content, and the March logging incident came from a custom guardrail returning too much data. In a Launch HN thread for a new open source gateway, commenters asked who reviews compiled plugins and suggested running third party extensions out of process. Keep a reviewed list and pin them.
What should you monitor for abuse?
Monitoring is about noticing when usage stops looking like your applications. These signals catch outside abuse, such as the LLMjacking Symantec describes, and inside compromise.
| Signal | What it may mean | Where to get it |
|---|---|---|
| Spend per key rising sharply against its own baseline | Stolen virtual key, runaway agent, denial of wallet | Gateway spend data, for example GET /key/info in LiteLLM |
| A key calling a model it has never used | Stolen key used for a different workload | Gateway logs of model per request |
| Requests from a new source address or network | Key used outside your infrastructure | Gateway access logs, ingress logs |
| New keys, budget increases or route changes outside change windows | Admin credential compromise | Gateway management audit log |
| Provider usage not matched by gateway records | Upstream key used directly, bypassing the gateway | Provider usage pages and admin APIs compared with gateway spend |
| Denied egress from the gateway | Something inside the gateway trying to reach an unapproved host | Egress proxy deny logs |
Calls to the cloud metadata address or GetCallerIdentity from the gateway role | Credential harvesting | Host network logs, CloudTrail |
| Unexpected processes or files in the container | Persistence after a bad install | Runtime monitoring, image drift checks |
A good first alert is provider usage the gateway did not record. If only the gateway uses your upstream keys, the numbers should match; when they do not, someone is using a key directly. For key inventory, Anthropic's Admin API lists active keys with their expiry and scope:
curl -sS "https://api.anthropic.com/v1/organizations/api_keys?status=active&limit=100" \
-H "x-api-key: $ANTHROPIC_ADMIN_KEY" \
-H "anthropic-version: 2023-06-01" \
| jq -r '.data[] | [.id, .name, .expires_at] | @tsv'
Run it on a schedule and alert on any active key missing from your inventory or lacking an expiry. OWASP LLM10:2025 also recommends rate limits, timeouts, input size limits and anomaly detection, and a gateway is the natural place to enforce them, one of the better arguments for having one.
Step by step: hardening a self-hosted gateway
If you already run a gateway, work in this order. Most teams finish steps 1 to 6 in a day.
-
Find every instance, including developer laptops and notebooks, where gateways often start life.
# Python environments pip show litellm 2>/dev/null | grep -E '^(Name|Version)' grep -RIn --include='*requirements*.txt' --include='pyproject.toml' --include='uv.lock' --include='poetry.lock' 'litellm' . # Running containers and manifests docker ps --format '{{.Image}}' | grep -i litellm kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | grep -i litellm -
Pin what you found: exact versions plus hashes, digests instead of tags, through review.
-
Close the network. Internal only, labelled callers only, management behind your VPN. Confirm from outside that management routes do not answer.
# from a machine outside your network; both should fail to connect curl -sS -o /dev/null -w '%{http_code}\n' https://llm.example.com/key/generate curl -sS -o /dev/null -w '%{http_code}\n' https://llm.example.com/ui -
Restrict egress to provider hostnames through a proxy, block the metadata address, alert on denies.
-
Turn off content logging, remove
log_raw_request_response, restrict access to spend logs and traces, and set retention. -
Reissue keys: one per application and environment, with model allowlist, budget, rate limits, expiry and route allowlist. Revoke shared keys.
-
Move upstream keys into your secrets manager, per environment, with expiry and provider spend limits.
-
Monitor: gateway versus provider spend, key inventory, egress denies, management changes.
-
Rehearse rotating the master key and one provider key end to end, so the first rotation is not during an incident.
Common mistakes
- A public load balancer for convenience. Use a VPN or identity aware proxy, and keep management routes private regardless.
- Pulling
latestor a moving branch tag. That is how a short lived bad image reaches production. - Treating a signature as proof of safety. It proves origin, not intent.
- Logging everything "for debugging". Content logs capture pasted secrets and tool outputs.
- Applications holding the master key. It mints other keys.
- Admin created keys with no owner, which can quietly carry admin rights.
- No provider side limits. Gateway budgets do nothing once the upstream key is stolen.
- Upgrading the gateway casually as a library. Give it an owner, a change process and a runbook.
- Reinstalling over a compromised environment. LiteLLM warns that Python startup re-runs planted files. Rebuild from scratch.
- Forgetting laptop copies that run next to coding agents.
Fix it without waiting for upstream
A gateway is an open source dependency and a container image like any other, and for a component holding every provider key you own, the gaps below are expensive.
In incidents like this one, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
For a gateway, Safeguard tracks it as a package and an image: safeguard scan --dir . covers repositories and lockfiles, safeguard scan --image covers images, and the platform shows which projects contain a given component and version. It does not manage your provider keys, configure your gateway's logging or restrict its egress. Those controls are yours to run.
FAQ
Is LiteLLM safe to use after the October 2026 compromise?
LiteLLM says all versions before 1.107.0 are considered safe and recommends pinning 1.106.2 or another explicit pre incident version. Whether it is safe for you depends on how you run it: pinned by hash or digest, private, with restricted egress and content logging off.
Do I need an LLM gateway if I only use one provider?
Usually not. Provider SDKs with a project or workspace per service and environment, expiring keys and provider spend limits give most of the control with fewer moving parts.
Can an LLM gateway leak my API keys?
Yes: a compromised release reads keys from the environment or database, logs capture authorization headers or tool outputs, or an exposed management route lets someone mint or read keys.
What is the safest way to store provider API keys for a gateway?
In a secrets manager, injected at runtime, scoped per environment, expiring, with a provider spend limit. Strongest of all, an egress proxy adds the key so the gateway holds only a placeholder.
Should the LiteLLM admin UI be public?
No. LiteLLM's June 2026 Host header advisory showed that a management route reachable by untrusted clients becomes unauthenticated access the moment an auth bug appears.
Should I log prompts and responses through my gateway?
Not by default. Prompts and tool outputs routinely contain secrets. Keep spend metadata and enable content capture only for specific keys with an owner and short retention.
Is a signed package or image enough to trust a gateway release?
No. On 21 October 2026 the attacker drove the real signing pipeline, so the bad artifacts were signed. Pair signatures with digest pinning, cooldowns and egress limits.
How do I know if someone is abusing my gateway or my keys?
Compare provider reported usage with gateway records, and alert on spend spikes per key, new models, new source addresses, key changes and denied egress.
What is LLMjacking and does it target gateways?
LLMjacking is running workloads on someone else's AI access through a stolen key or exposed endpoint. Symantec, reported by Infosecurity Magazine, describes an attack agent that hunts exposed AI gateways and MCP servers for exactly this.
See how Safeguard would help
These are real product sessions. None hardens a gateway's network or keys for you; they show finding where a component version runs and moving it to a safe one, with a human approving each step.
This CLI session installs Safeguard, opens the interactive terminal and asks it to fix the lodash CVE in a repository. It reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with approval, and pushes nothing. The same flow applies to moving a gateway pin in requirements.txt, followed by the /scan . check at the end.
Click through it at your own pace, or open it full screen.
This demo sets up the Safeguard runner on your own machine, approves it with its device code, then scans from the terminal. Gateway teams can use it to scan the repositories and lockfiles that carry the gateway from inside their own network.
Click through it at your own pace, or open it full screen.
This demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. It is the scoped virtual key principle again: the assistant gets only the tools you allow, so an engineer can ask about gateway versions without granting broad access.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard or read the CLI documentation.
Quick check
Why did a valid signature not protect users from the October 2026 LiteLLM release?
Because the attacker used stolen developer credentials to point the project's own release workflow at a lookalike repository. The real pipeline built, signed and published the bad artifacts, so the signature was genuine. Digest pinning, cooldowns and egress limits are what would have contained it.
What is the single most useful network control for a self-hosted LLM gateway?
An egress allowlist. If the gateway can reach only your provider hostnames, its database and DNS, a credential stealer running inside it cannot send what it collects, and the denied connection becomes an alert.
Sources
- LiteLLM: Contained, Oct 21, 2026 LiteLLM release v1.107.0 compromised
- LiteLLM: Suspected supply chain incident (March 2026)
- LiteLLM: Guardrail logging exposed secret headers in spend logs and traces
- LiteLLM: Host header authentication bypass (GHSA-4xpc-pv4p-pm3w)
- LiteLLM blog: security posts
- LiteLLM docs: Virtual keys
- LiteLLM docs: Logging
- Hacker News discussion of the LiteLLM 1.107.0 compromise
- Hacker News: Launch HN discussion of an open source Rust AI gateway
- Infosecurity Magazine: Symantec on an AI agent built for LLMjacking
- OWASP GenAI Security Project: LLM10:2025 Unbounded Consumption
- OWASP Logging Cheat Sheet
- OpenAI: Production best practices
- Anthropic: Admin API
- pip: Secure installs (hash checking mode)
- PyPI: Trusted Publishers security model
- Docker: docker image pull (pull by digest)
- Safeguard: LiteLLM 1.107.0 PyPI compromise
Last reviewed: 22 October 2026. The LiteLLM investigation is ongoing; check the maintainer's incident post for the latest status and safe versions.