Air-Gapped Deployments
Sentinel runs in a fully air-gapped environment — no outbound internet access at all — once two things are handled: license verification has to work offline, and every feature that fetches a remote data source has to be either disabled or pointed at a mirror on your own network.
Nothing about the core request path (/v1/challenge, /v1/verify, the dashboard, the management API) needs outbound access. The connections below are all made by background jobs, and the widget itself never talks to the internet beyond your own Sentinel origin.
Outbound connections Sentinel makes
| Destination | Purpose | Air-gapped handling |
|---|---|---|
eu.altcha.org | License verification (call-home) | Use LICENSE_JSON — offline licensing |
| FireHOL / Spamhaus / Tor / BotScout lists | Threat Intelligence IP feeds | Disable, or add custom sources |
| PhishTank feed | Phishing Detection | Disable via PHISHING_LIST_URL=, or mirror |
disposable-email-domains list | Throwaway-email detection | Disable via EMAIL_LIST_DISPOSABLE=, or mirror |
intoli/user-agents dataset | Suspicious user-agent detection | Disable via USER_AGENT_LIST_URL=, or mirror |
| MaxMind / ipinfo.io | GeoIP lookups — see IP Resolvers | Mirror the database download URL, or leave unset |
| AI provider API | AI Security Rules | Use a self-hosted model (ollama), or leave unset |
Offline licensing
By default Sentinel verifies your license periodically by contacting eu.altcha.org (application version, Node ID, and process ID only — no traffic or visitor data). In an air-gapped deployment this call will fail, so configure the license offline instead:
Set LICENSE_JSON to the full contents of the license file attached to your purchase-confirmation email, in place of LICENSE_KEY:
LICENSE_JSON={"...":"..."}With LICENSE_JSON set, Sentinel validates the license locally and never calls home. A paid Professional or Enterprise license is required — the 30-day trial and multi-replica clustering limits still apply. See License for details.
Disabling remote data sources
Each of these features downloads a list on a schedule. Disable the ones you don't intend to mirror — a disabled feature is skipped cleanly, it doesn't retry or log errors.
# Threat Intelligence — FireHOL and other IP reputation feeds
THREATS_ENABLED=0
# Phishing Detection — PhishTank feed
PHISHING_LIST_URL=
# Disposable / throwaway email detection
EMAIL_LIST_DISPOSABLE=
# Suspicious user-agent detection
USER_AGENT_LIST_URL=Setting a *_LIST_URL variable to an empty string turns that feature off entirely. THREATS_ENABLED=0 disables Threat Intelligence including its live-traffic detection.
Geolocation
If you use MaxMind or ipinfo.io for country/ASN lookups, either leave the credentials unset (geolocation-based rules simply won't fire) or mirror the database — see the next section. Header-based geolocation like CLOUDFLARE_IP_COUNTRY_ENABLED needs no outbound access and keeps working.
AI Security Rules
Point AI_PROVIDER at a model running inside your network — ollama with AI_PROVIDER_OPTIONS set to a local base URL — or leave AI_PROVIDER unset to disable AI rules. See AI Providers.
Custom and mirrored sources
Rather than losing a feature, host its data on an HTTP server inside your air-gapped network and point Sentinel at that.
Lists — override the source URL with your internal mirror. Sentinel re-fetches when the file changes, using ETag / Last-Modified, so your mirror should send at least one of those headers. Basic auth is supported, in an Authorization header or embedded in the URL.
PHISHING_LIST_URL=https://mirror.internal/phishing.csv
EMAIL_LIST_DISPOSABLE=https://mirror.internal/disposable-email-domains.txt
USER_AGENT_LIST_URL=https://mirror.internal/user-agents.json
MAXMIND_DOWNLOAD_URL=https://mirror.internal/GeoLite2-City.mmdb
IPINFO_IO_MMDB_DOWNLOAD_URL=https://mirror.internal/ipinfo.mmdbAdjust the matching *_SCHEDULE variables to control how often each mirror is polled — see ENV Variables.
Threat Intelligence blocklists — with THREATS_ENABLED=1, remove the default FireHOL/Spamhaus/Tor sources and add your own custom blocklists from the admin app (Root privileges required): any remote HTTP server serving .csv, .txt, .ipset, or .netset (one IP or CIDR per line). In an air-gapped setup that server is a host on your own network, refreshed by whatever process you use to bring updated feeds across the boundary. See Threat Intelligence and Data Sources.
Verifying
After starting Sentinel with no internet route, confirm it's healthy:
- The dashboard loads and Admin → License shows your license as valid (not "trial").
- Monitoring & Logging shows no repeated outbound-connection errors from the list/feed update jobs.
- A test request through
/v1/challengeand/v1/verifycompletes normally.
Related
- License —
LICENSE_JSONand offline verification in full. - ENV Variables — every variable referenced here, including
HTTP_PROXY/NO_PROXYand the*_SCHEDULEupdate jobs. - Threat Intelligence and Data Sources — the feeds and custom-source configuration.
- Clustering — running multiple replicas, with license-enforced limits that still apply offline.