Network Allow-List¶
PolicyClue is designed to run in restricted, on-premise networks. Most external connections come from optional modules - disable the module and the hostname disappears from this list. This page lists every external host the stack contacts, the direction (inbound/outbound), the protocol/port to allow, and how to turn each one off.
Each section is labelled with its network role so firewall rules and documentation stay unambiguous.
Inbound - end users and Microsoft¶
| Direction | Port | Source | Purpose |
|---|---|---|---|
| Inbound | TCP/80 | End users / Let's Encrypt | HTTP entry point on Traefik. With the ACME override, used for the HTTP-01 challenge and a redirect to HTTPS. Without the override, this is the portal entry point - keep it behind your own TLS terminator. |
| Inbound | TCP/443 | End users | HTTPS entry point. Only opened on the host when the docker-compose-acme.yml override is active or you terminate TLS at Traefik yourself. |
| Inbound | TCP/443 | Microsoft Graph | Webhook delivery to /api/m365/notifications. Only when M365 DLP is configured. See the Microsoft Teams DLP section in Deployment for narrow path-only exposure. |
Outbound - always required¶
| Direction | Host | Port | Purpose |
|---|---|---|---|
| Outbound | registry.khost.ch |
TCP/443 (HTTPS) | PolicyClue container image registry (API + webapp images). Only contacted on docker compose pull / up. Mirror to a private registry to avoid runtime egress. |
| Outbound | registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com |
TCP/443 (HTTPS) | Docker Hub - source for the postgres, redis, and traefik base images pulled by docker compose pull / up. All three hostnames are needed together (registry API, auth, and image-blob CDN). |
| Outbound | docker.elastic.co |
TCP/443 (HTTPS) | Elastic's own container registry - source of the Elasticsearch image. Only contacted on docker compose pull / up. |
| Outbound | The host in SERVICES_GATE_URL (default pclue.kgq.ch) |
TCP/443 (HTTPS) | PolicyClue services gateway. Covers sandbox analysis, vulnerability lookups, BAS mail relay, LLM inference, and hostlist sync - one host, basic-auth per instance. Required at API startup; the portal refuses to boot without SERVICES_GATE_URL, SERVICES_GATE_USER, and SERVICES_GATE_PASSWORD. |
| Hostlist sync (UT1 blacklist archive, several awesome-list READMEs, one social-URL gist) is fetched through the services gateway now — no direct outbound to github.com / codeload.github.com / raw.githubusercontent.com / gist.githubusercontent.com is required from the customer's network. The gateway relays and caches the responses with a 24-hour TTL so even during GitHub outages the customer's next sync gets the last-known-good copy. |
Without the GitHub hosts, hostlists stay on the last cached version - the portal keeps working.
Outbound - reverse proxy / TLS¶
| Direction | Host | Port | When |
|---|---|---|---|
| Outbound | acme-v02.api.letsencrypt.org (or your ACME_CASERVER) |
TCP/443 (HTTPS) | Only when docker-compose-acme.yml is enabled. Skip if you terminate TLS at an upstream proxy or use a private CA. |
The HTTP-01 challenge also requires inbound TCP/80 to be reachable from the public internet during certificate issuance and renewal.
Outbound + Inbound - Microsoft 365 (SSO and DLP modules)¶
Active when MSENTRA_CLIENT_ID, MSENTRA_CLIENT_SECRET, and
MSENTRA_TENANT_ID are set, or when any tenant has the M365 DLP module
configured.
| Direction | Host | Port | Purpose |
|---|---|---|---|
| Outbound | login.microsoftonline.com |
TCP/443 (HTTPS) | Entra ID authentication. |
| Outbound | graph.microsoft.com |
TCP/443 (HTTPS) | Microsoft Graph API. |
| Inbound | Portal (/api/m365/notifications) |
TCP/443 (HTTPS) | Microsoft Graph webhook delivery. If the portal is not publicly reachable, expose only this path through a tunnel or reverse proxy. |
To disable: leave the three MSENTRA_* variables empty.
Outbound - SMTP (transactional mail and BAS)¶
The stack does not connect to a fixed SMTP host - mail delivery uses customer-provided servers. The port depends on the security mode you configure:
| Mode | Typical port | Notes |
|---|---|---|
Implicit TLS (MAIL_SECURITY=tls) |
TCP/465 | Default in .env.example. |
STARTTLS (MAIL_SECURITY=starttls) |
TCP/587 | Submission port. |
Plain (MAIL_SECURITY=none) |
TCP/25 | Internal relays only - never use to a public MTA. |
| Direction | Variable | Notes |
|---|---|---|
| Outbound | MAIL_HOST + MAIL_PORT |
Transactional mail. Allow whatever host/port pair you set. |
BAS phishing-mail sending goes through the central services gateway
(SERVICES_GATE_URL) - no extra outbound rules needed beyond the
gateway host already covered above.
To disable: leave MAIL_HOST empty for transactional mail; disable the
bas module per tenant to skip the gateway's mail relay.
LLM override (self-hosted)¶
Set OVERRIDE_LLM_BASE_URL to bypass the gateway for AI features
(e.g. use your own Ollama or LiteLLM). Allow whichever host you point
at instead.
| Mode | Host to allow | Port |
|---|---|---|
| Override: Self-hosted Ollama | None at runtime - internal Docker network only. First-time model pull only: registry.ollama.ai. |
TCP/443 (HTTPS) for the model pull |
| Override: OpenAI direct | api.openai.com |
TCP/443 (HTTPS) |
| Override: LiteLLM proxy | The proxy hostname only - it talks to providers on your behalf. | TCP/443 (HTTPS), or whatever the proxy listens on |
What the portal does not contact¶
To keep the allow-list short:
- No analytics, error-reporting, or product-telemetry services.
- No public CDNs from the webapp. Fonts, icons, charting, grids, and the rich-text editor are vendored into the webapp image and served from the portal itself - no third-party asset hosts in browser traffic.
- No license verification servers. Licensing is validated locally.
Quick reference¶
Minimal on-prem¶
No SSO, no Security module, no AI, no BAS.
| Direction | Host | Port | Purpose |
|---|---|---|---|
| Inbound | Portal | TCP/80 (and/or TCP/443 if you terminate TLS) | End-user access |
| Outbound | registry.khost.ch |
TCP/443 | PolicyClue image registry (API + webapp) |
| Outbound | registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com |
TCP/443 | Docker Hub (postgres, redis, traefik images) |
| Outbound | docker.elastic.co |
TCP/443 | Elastic registry (Elasticsearch image) |
| Outbound | pclue.kgq.ch |
TCP/443 | Services gateway |
Full on-prem¶
Everything enabled - Entra SSO, M365 DLP, Security module, BAS, Ollama LLM, Let's Encrypt TLS.
| Direction | Host | Port | Purpose |
|---|---|---|---|
| Inbound | Portal | TCP/80 | ACME HTTP-01 challenge + HTTPS redirect |
| Inbound | Portal | TCP/443 | End-user HTTPS access |
| Inbound | Portal /api/m365/notifications |
TCP/443 | Microsoft Graph webhooks |
| Outbound | registry.khost.ch |
TCP/443 | PolicyClue image registry (API + webapp) |
| Outbound | registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com |
TCP/443 | Docker Hub (postgres, redis, traefik images) |
| Outbound | docker.elastic.co |
TCP/443 | Elastic registry (Elasticsearch image) |
| Outbound | acme-v02.api.letsencrypt.org |
TCP/443 | Let's Encrypt certificate issuance |
| Outbound | login.microsoftonline.com |
TCP/443 | Entra ID authentication |
| Outbound | graph.microsoft.com |
TCP/443 | Microsoft Graph API |
| Outbound | pclue.kgq.ch |
TCP/443 | Services gateway |
| Outbound | registry.ollama.ai |
TCP/443 | Ollama model pull (first time only) |
| Outbound | <your MAIL_HOST> |
TCP/465 (TLS) or TCP/587 (STARTTLS) | Transactional mail |