Skip to main content
Custom hosts with private network routing — including the TRUSTED_CUSTOM_HOSTS allowlist — applies only to hybrid and air-gapped enterprise deployments of the Portkey AI Gateway. On Portkey SaaS, custom host URLs must be publicly reachable; routing to private or internal network IPs is not supported.
The custom_host parameter routes Portkey Gateway requests to your own model endpoints — whether running locally, in a private cloud, or on custom infrastructure. Portkey validates all custom host URLs to prevent SSRF attacks.

Setting a custom host

Specify a custom host using one of these methods:
Also set custom_host in a Gateway config target:
Include the version path (e.g., /v1) in the custom_host URL. Portkey appends the endpoint path (/chat/completions, /responses, etc.) automatically.
forward_headers cannot include cloud metadata headers such as metadata-flavor, x-aws-ec2-metadata-token, or x-google-metadata-request, or the x-portkey-forward-headers header itself.
For a full guide on integrating private LLMs, see Bring Your Own LLM.

How validation works

Portkey applies SSRF checks at two layers on Node.js deployments:
  1. Request time — When a custom_host URL is accepted, the gateway validates the hostname, port, scheme, and URL shape before the request proceeds.
  2. Connection time — On outbound requests, DNS resolution validates every returned IP against the same rules and pins the connection to safe addresses. This blocks DNS rebinding attacks where a hostname initially resolves to a public IP but later resolves to a private or metadata address.
On Cloudflare Workers, request-time validation still applies; connection-time DNS pinning is a Node.js-only hardening layer. URLs must use http:// or https://, must not embed credentials, and are capped at 2048 characters.

Blocked host patterns

Portkey validates all custom host URLs to prevent requests to internal network resources. The following IP ranges and patterns are blocked by default (unless the hostname is explicitly trusted — see Trusted custom hosts (allowlist)).

Private IPv4 ranges

Reserved IPv4 ranges

Cloud metadata endpoints

These addresses are always blocked and cannot be allowlisted:

Single-label blocked hostnames

These bare hostnames are always blocked (they often resolve to internal services via DNS search domains):

Blocked hostname suffixes

Subdomains of known cloud metadata and internal service FQDNs are blocked, including (but not limited to):
  • metadata.google.internal, metadata.gce.internal, metadata.goog
  • metadata.azure.com, internal.cloudapp.net
  • metadata.internal, metadata.do.internal, metadata.packet.net
  • instance-data.ec2.internal, ec2.internal, compute.internal
  • metadata.cloud.ibm.com
  • kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local
  • cluster.local
  • consul (and *.service.consul, *.node.consul)
These suffix checks run before the trusted-host allowlist and cannot be overridden.

Wildcard DNS rebinding services

Hostnames that encode arbitrary IPs in the DNS label are blocked:

Blocked internal TLDs

Hostnames ending in these TLDs are blocked unless explicitly trusted: .local, .localdomain, .internal, .intranet, .lan, .home, .corp, .test, .invalid, .onion, .localhost

IPv6 local and private ranges

IPv6 addresses with embedded IPv4

IPv6 literals that embed a blocked IPv4 address are rejected, including:
  • IPv4-mapped (::ffff:127.0.0.1)
  • IPv4-compatible (::127.0.0.1, ::7f00:1)
  • 6to4 (2002:7f00:1::)
  • NAT64 (64:ff9b::7f00:1)
Public IPv6 addresses such as 2001:4860:4860::8888 remain allowed.

IP obfuscation tricks

The following alternate IP representations are also blocked to prevent bypass attempts:
  • Decimal form — e.g., 2130706433 (resolves to 127.0.0.1)
  • Hexadecimal form — e.g., 0x7f000001 (resolves to 127.0.0.1)
  • Shortened IPv4 — e.g., 127.1 (resolves to 127.0.0.1)
  • Octal notation — e.g., 0177.0.0.1 (resolves to 127.0.0.1)
  • Percent-encoded hostnames — e.g., %31%32%37...
  • Punycode labels — hostnames containing xn-- labels

Blocked ports

Even for trusted hostnames, Portkey blocks ports commonly used by non-HTTP internal services (SSH, databases, caches, admin APIs, etc.). Examples include 22, 25, 445, 3306, 5432, 6379, 6443, 9200, and 27017. HTTP and HTTPS service ports (such as 80, 443, 8000, 8080, 8443) are allowed. Ports must be between 1 and 65535.

Trusted custom hosts (allowlist)

Portkey maintains a trusted hosts allowlist via the TRUSTED_CUSTOM_HOSTS environment variable. Trusted hostnames bypass private/reserved IP range checks at request time, and their DNS-resolved addresses bypass private/reserved IP checks at connection time.
TRUSTED_CUSTOM_HOSTS is available only on self-hosted hybrid and air-gapped enterprise deployments of the Portkey AI Gateway.

Default behavior

When setting TRUSTED_CUSTOM_HOSTS in non-production, include the default values (localhost, 127.0.0.1, ::1, host.docker.internal) along with your additions if you still need local development access.

Adding hosts to the allowlist

To route to a private network IP (e.g., 172.31.2.45), add it to the trusted hosts allowlist using the TRUSTED_CUSTOM_HOSTS environment variable. Set the environment variable as a comma-separated list of hosts:
Requests with custom_host set to http://172.31.2.45:8008/v1/ will then pass validation.

Entry format

Each entry can be: Wildcard entries (*.domain) are supported in TRUSTED_CUSTOM_HOSTS. Subdomains are not inherited from a bare domain entry — example.com does not allow api.example.com. To trust subdomains, add an explicit wildcard entry such as *.example.com. Entries with schemes, ports, or paths are normalized automatically. Wildcard entries (*.) cannot target IP literals. When localhost is trusted, subdomains ending in .localhost (e.g., api.localhost) are also allowed.
Cloud metadata endpoints, metadata FQDN suffixes, and wildcard DNS rebinding domains cannot be allowlisted. Entries that overlap always-blocked ranges are silently dropped from TRUSTED_CUSTOM_HOSTS.

Validation rules for trusted hosts

Even for trusted hosts, Portkey enforces:
  • Port range — The port must be between 1 and 65535, and must not be on the blocked-ports list
  • Host-only matching — Only the hostname or IP is checked against the allowlist, not the full URL
  • IP literals are exact-match only — Trusting 127.0.0.1 does not unlock x.127.0.0.1
  • Subdomains require a wildcard — Trusting example.com does not unlock api.example.com; add *.example.com to cover subdomains
  • Always-blocked overrides — Cloud metadata, IMDS subnets, blocked hostname suffixes, wildcard rebinding domains, and dangerous IPv6-embedded-IPv4 forms remain blocked even when trusted

Common scenarios

Last modified on June 15, 2026