AdministrationNetwork allowlist

Network allowlist

Neens calls your LLM connections from its own servers. To stop a connection from being used to reach internal systems, Neens refuses any connection whose address is private (a 10.x, 172.16–31.x or 192.168.x address, or a host name that resolves to one) unless that host is on your company’s network allowlist. Add your private model gateway or self-hosted model here and every judge, insight, assistant reply and other LLM feature can use it. Your list applies only to your company; no other company can use it.

At a glance

WhereSettings → Network allowlist
APIGET /api/settings/llm-allowed-hosts, PUT /api/settings/llm-allowed-hosts
ListsCompany-wide (every agent in your company) and This agent only (extra hosts for one agent)
Entry typesExact host name, IP address, or CIDR range
Who can editCompany-wide list: a company-wide admin. Agent list: an admin with access to that agent. Everyone else can view
LimitUp to 50 entries per list
AuditEvery change is recorded in the audit log as egress_allowlist.update, with the list before and after

When you need it

You only need the allowlist when an LLM connection points somewhere that is not on the public internet, for example:

  • a model gateway inside your network, such as https://llm-gateway.internal.example.com/v1;
  • a self-hosted model server (vLLM, Ollama, LM Studio) on a private address;
  • an entire private subnet where your model servers live, such as 10.20.0.0/16.

Public endpoints (OpenAI, Anthropic, Google, OpenRouter, a public LiteLLM proxy) never need an entry.

Add a host in Settings

Open Settings → Network allowlist

Everyone can open the screen. If you can’t edit a list, the screen tells you who can.

Choose the list

Use Company-wide for hosts every agent in your company should reach. Use This agent only for a host just the agent you have selected should reach (for example, a model server dedicated to one team). An agent can reach the company-wide hosts plus its own.

Enter the host, IP address or CIDR range

Type an exact host name (llm-gateway.internal.example.com), an IP address (10.20.0.5) or a CIDR range (10.20.0.0/16), then select Add. The list saves immediately. If the entry isn’t accepted, the reason appears under the field.

Test the connection

Go back to Settings → LLM providers and click Test on the connection. It should now reach your host.

To remove an entry, select Remove next to it. Changes take effect within a minute.

Manage the list with the API

Use an API key or a session token in the Authorization header. Reading works with any credential that can see the agent; changing a list needs an admin user, so a project API key (nk_live_…) can read the lists but gets 403 on PUT. In the examples below, $ADMIN_TOKEN stands for the session token of a signed-in admin.

curl -s https://neens.example.com/api/settings/llm-allowed-hosts \
  -H "Authorization: Bearer nk_live_…"
{
  "projectId": "project_123",
  "selfServiceEnabled": true,
  "maxEntries": 50,
  "platformManaged": [],
  "company": {
    "entries": [
      {"entry": "10.20.0.0/16", "addedAt": "2026-10-01T09:12:00+00:00", "addedByName": "Ava Lindqvist"},
      {"entry": "llm-gateway.internal.example.com", "addedAt": "2026-10-01T09:12:00+00:00", "addedByName": "Ava Lindqvist"}
    ],
    "canEdit": false
  },
  "project": {"entries": [], "canEdit": false}
}

PUT replaces the whole list for that scope with entries (send [] to clear it) and returns the same body as GET. scope defaults to company.

{
  "projectId": "project_123",
  "selfServiceEnabled": true,
  "maxEntries": 50,
  "platformManaged": [],
  "company": {
    "entries": [
      {"entry": "llm-gateway.internal.example.com", "addedAt": "2026-10-02T14:03:00+00:00", "addedByName": "Ava Lindqvist"},
      {"entry": "10.20.0.0/16", "addedAt": "2026-10-02T14:03:00+00:00", "addedByName": "Ava Lindqvist"}
    ],
    "canEdit": true
  },
  "project": {"entries": [], "canEdit": true}
}
Responses and error codes
Statusdetail.errorMeaning
200Saved. The body is the updated allowlist
403company_admin_requiredYou are an admin for some orgs only; the company-wide list reaches agents outside them
403self_service_disabledSelf-service is turned off for your account; contact your Neens administrator. Saved entries are not in effect
403(text)Your role can’t change the allowlist (members, viewers and API keys)
422invalid_entriesOne or more entries were rejected. detail.errors lists each one with its index, code and message
422invalid_scopescope must be company or project

Entry error codes: invalid_host, invalid_cidr, wildcard_not_allowed, url_not_allowed, port_not_allowed, cidr_too_broad, always_refused, internal_name_not_allowed, ipv6_transition_not_allowed, empty_entry, and too_many_entries (reported once, with index: -1).

Entry rules

You enterAccepted?Notes
llm-gateway.internal.example.comYesMatched exactly by name, case-insensitively. Any port on that host is allowed
10.20.0.5YesOne address
10.20.0.0/16YesEvery address in the range. Saved in canonical form (10.20.1.7/16 becomes 10.20.0.0/16)
*.internal.example.comNoWildcards aren’t supported: list each host name
gateway, vllm.default.svc.cluster.localNointernal_name_not_allowed: single-word names and cluster-internal service names (.svc, .cluster.local) can’t be listed. Use your gateway’s fully qualified name or its IP address
https://gw.example.com/v1 or gw.example.com:8080NoEnter only the host, without a scheme, path or port
10.0.0.0/7, 0.0.0.0/0NoToo broad. The widest range is /8 for IPv4 and /32 for IPv6
169.254.169.254, fe80::/64, 127.0.0.2NoAlways refused (see below)
64:ff9b::/96, 2002::/16Noipv6_transition_not_allowed: IPv6 translation ranges (NAT64, 6to4, Teredo) can’t be listed. List the IPv4 address or range instead

What is always refused

Some addresses are refused even if you list them, because reaching them from Neens’ servers would expose the platform itself rather than your model:

  • Cloud metadata endpoints, such as 169.254.169.254 and metadata.google.internal, which hand out server credentials;
  • link-local addresses (169.254.0.0/16, fe80::/10);
  • loopback addresses, the unspecified address, and multicast;
  • address ranges reserved by the platform for its own infrastructure.

The check runs when Neens connects, after looking up the host name, not just when you save. A host name on your list that resolves to one of these addresses is still refused, and so is one that resolves to several addresses if any of them is refused.

Only list hosts you control. An entry lets every LLM feature of the agents it covers send prompts, which can include trace content, to that host.

Troubleshooting

SymptomLikely causeFix
Saving or testing a connection fails with “is a private/loopback/link-local address and is not on the network allowlist”The base URL is a private IP address that isn’t listed for your company or agentAdd the IP or its CIDR range to the Company-wide list or This agent only
Test fails with “The base URL’s host resolves to a private address that is not on the network allowlist…”The base URL’s host name resolves to a private address that isn’t listedAdd the exact host name (or the address range it resolves to)
A judge or other LLM feature errors with “LLM connection base_url is not allowed”Same as above, seen when the feature runsAdd the host, then re-run
The error says the address “is always refused”The host is, or resolves to, a metadata, link-local, loopback or platform-reserved addressPoint the connection at a different address. These can’t be allowlisted
It works for one agent but not anotherThe host is on This agent only for the first agentAdd it to the Company-wide list, or to the other agent’s own list
The screen says editing is turned offSelf-service is turned off for your accountContact your Neens administrator; while it is off, saved entries are not in effect
You can view but not editYou aren’t an admin, or (for the company-wide list) you are an admin for some orgs onlyAsk a company-wide admin