Your Hugging Face org declares its IP ranges in CIDR, and Enterprise Plus network restrictions apply to access tokens too. Route Hub API calls, model downloads, and Inference through two fixed static EU IPs.
# .env
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
HF_TOKEN=hf_...
import requests
# huggingface_hub is requests-based,
# so HTTPS_PROXY covers it too
r = requests.get(
"https://huggingface.co/api/whoami-v2",
headers={"Authorization": "Bearer hf_..."})
Hugging Face Network Security on Enterprise Plus restricts your organization to the CIDR IP ranges your admins declare. Everything else about your infrastructure is moving.
Organization IP Ranges are fixed CIDR blocks in your Network Security settings. But CI runners, serverless functions, and container platforms hand your jobs a different outbound address on every run. The moment it lands outside a declared range, access to your org's models and datasets is refused.
When "Restrict organization access to your IP ranges only" is enabled, Hugging Face applies the rules to access tokens as well, not just browser sessions. The hf_... token in your training job is subject to the same CIDR check, so automation breaks in exactly the same way interactive traffic does.
One documented escape hatch is exempting a service account token from network restrictions so automation can run outside your ranges. That turns a tightly scoped credential into one valid from anywhere. The other is whitelisting your cloud provider's entire regional CIDR blocks, which admits every other tenant sharing those pools.
Hugging Face verifies your Organization IP Ranges jointly with your admins before certain settings activate, and range changes mean another verification round. If your egress keeps moving, you either schedule constant reviews with their Solution Engineers or let the settings drift out of date and fail closed.
Training job, CI, app
HTTPS Proxy
(Two static EU IPs)
huggingface.co
Declare your two OutboundGateway addresses as single-host CIDR entries, one per line, and every request your org makes to the Hub lands inside the allowlist. Browser sessions, fine-grained access tokens, and headless automation all pass the same range check.
huggingface_hub is built on requests, so HTTPS_PROXY routes Hub API calls, model files, and Inference with no code changes.
Running CI pipelines and fine-tuning jobs that pull base models and push checkpoints, and needing them all to clear the org's IP range check.
Downloading models and datasets from runners and notebooks that live on cloud platforms with rotating egress addresses.
Own the Enterprise Plus Network Security settings and want the smallest defensible set of allowed ranges rather than cloud-sized CIDR blocks.
Documenting where prompts, inference traffic, and dataset content originate, under GDPR and the EU AI Act's documentation expectations.
Set HTTPS_PROXY, then register your two IPs in Network Security settings.
The official SDK is requests-based, so the standard proxy env var covers Hub API calls and model downloads with zero code changes.
# .env
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
HF_TOKEN=hf_...
import os
import requests
from huggingface_hub import HfApi
# Confirm the egress Hugging Face will see
r = requests.get("https://huggingface.co/api/whoami-v2",
headers={"Authorization":
f"Bearer {os.environ['HF_TOKEN']}"})
print("authed as", r.json()["name"])
# SDK traffic rides the same proxy, no extra config
api = HfApi(token=os.environ["HF_TOKEN"])
info = api.model_info("meta-llama/Llama-3.1-8B-Instruct")
print(info.id)
Node's built-in fetch ignores proxy env vars, so install undici and set a global dispatcher once.
// npm install undici
import { setGlobalDispatcher, ProxyAgent } from 'undici';
setGlobalDispatcher(new ProxyAgent(process.env.HTTPS_PROXY));
const res = await fetch('https://huggingface.co/api/whoami-v2', {
headers: { 'Authorization': `Bearer ${process.env.HF_TOKEN}` },
});
console.log(await res.json());
Set it wherever the job runs. Keep the proxy URL in a secret, never in the image.
# Docker Compose
services:
trainer:
env_file: .env
# Kubernetes: Secret
env:
- name: HTTPS_PROXY
valueFrom:
secretKeyRef:
name: outboundgateway-proxy
key: proxy-url
Organization admins enter ranges under Network Security settings, one CIDR per line. Both of your addresses go in, because connections alternate between them and failover uses the pair.
# Organization IP Ranges (one per line)
203.0.113.10/32
203.0.113.42/32
# Then enable:
# "Restrict organization access to your IP ranges only"
# Manage programmatically:
# GET /api/organizations/<org>/settings/network-security
# PATCH /api/organizations/<org>/settings/network-security
Register both IPs, always
Your account comes with two static IP addresses and traffic uses either one, per connection. Add each as its own /32 line in your Organization IP Ranges. If one proxy node is briefly down, the other keeps serving and both stay inside your declared ranges.
📖 Complete Documentation: For detailed examples, error handling, and other Python libraries, see the Python SSL Proxy Guide, Node.js Guide, and all other language guides.
Hub traffic is rarely empty: prompts, inference payloads, dataset rows. EU teams generally want that path to stay on European infrastructure.
The proxy runs in EU data centres, so requests to the Hub leave from European addresses. That residency detail counts when dataset content includes personal data.
TLS passes through untouched, so the proxy cannot decode your access token, your prompts, or the dataset rows in transit. It forwards encrypted bytes, nothing more.
Traffic to the Hub doesn't hop through US infrastructure first, which removes a recurring question from GDPR transfer assessments of your AI stack.
When someone asks where your model traffic originates, the answer is two named EU addresses that also appear verbatim in your Hub Network Security settings. One story, two systems, no gaps.
Two addresses to declare as /32 ranges, with automatic failover between them, so your org allowlist never rests on a single node.
Set the proxy variable and huggingface_hub, requests, and transformers downloads all route through it unchanged.
European data centres and a GDPR-conscious setup, giving your model traffic a predictable European origin.
Repo metadata, dataset pulls, model weights, and Inference: anything you reach at huggingface.co goes out through the same stable pair.
TLS passthrough means the proxy can't read your traffic. Tokens, prompts, and dataset contents stay private the whole way.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
Stop widening your IP ranges or exempting tokens to keep automation alive. Route everything through two fixed EU IPs and declare them once.
€19/month starter plan • 7-day refund policy • Direct founder support
Yes. Once "Restrict organization access to your IP ranges only" is enabled, the CIDR rules govern org resources generally, and Hugging Face's documentation states they also apply to access tokens. That is exactly why headless jobs need a stable egress: a token used from an unlisted address fails the same range check a browser session would.
Organization IP Ranges take one CIDR entry per line, so each address becomes its own /32 line, for example 203.0.113.10/32. Register both of your IPs. Connections are distributed across the pair and failover moves traffic between them, so a single entry would cause intermittent blocks.
Yes. The Python SDK is built on requests, which reads HTTPS_PROXY from the environment automatically. Hub API calls, snapshot_download, and dataset fetches all follow it without any code changes. In Node.js, install undici and set a ProxyAgent dispatcher, since built-in fetch ignores proxy env vars.
Happy to talk through how a two-IP EU egress fits your Hub workflows, from CI model pulls to production Inference behind Enterprise Plus network restrictions.
Contact Our Founders →