# 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](#offline-licensing) |
| FireHOL / Spamhaus / Tor / BotScout lists | [Threat Intelligence](/docs/sentinel/features/threat-intelligence/) IP feeds | Disable, or add [custom sources](#custom-and-mirrored-sources) |
| PhishTank feed | [Phishing Detection](/docs/sentinel/features/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](/docs/sentinel/integrations/ip-resolvers/) | Mirror the database download URL, or leave unset |
| AI provider API | [AI Security Rules](/docs/sentinel/integrations/ai-security-rules/) | Use a self-hosted model (`ollama`), or leave unset |

> **Tip:**
>
> If your network allows outbound traffic only through an approved proxy rather than blocking it entirely, you may not need to disable anything — set `HTTP_PROXY` / `HTTPS_PROXY` (and `NO_PROXY` for internal hosts) and Sentinel routes all of its own outbound requests through it. See [ENV Variables](/docs/sentinel/operations/env-variables/#security--access).

## 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](/docs/sentinel/operations/clustering/) limits still apply. See [License](/docs/sentinel/security/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.

```bash
# 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](/docs/sentinel/integrations/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.

```bash
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.mmdb
```

Adjust the matching `*_SCHEDULE` variables to control how often each mirror is polled — see [ENV Variables](/docs/sentinel/operations/env-variables/#lists-phishing-disposable-email-user-agents).

**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](/docs/sentinel/features/threat-intelligence/#data-sources) and [Data Sources](/docs/sentinel/integrations/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](/docs/sentinel/operations/monitoring-logging/) shows no repeated outbound-connection errors from the list/feed update jobs.
- A test request through `/v1/challenge` and `/v1/verify` completes normally.

## Related

- **[License](/docs/sentinel/security/license/)** — `LICENSE_JSON` and offline verification in full.
- **[ENV Variables](/docs/sentinel/operations/env-variables/)** — every variable referenced here, including `HTTP_PROXY` / `NO_PROXY` and the `*_SCHEDULE` update jobs.
- **[Threat Intelligence](/docs/sentinel/features/threat-intelligence/)** and **[Data Sources](/docs/sentinel/integrations/data-sources/)** — the feeds and custom-source configuration.
- **[Clustering](/docs/sentinel/operations/clustering/)** — running multiple replicas, with license-enforced limits that still apply offline.
