Network flow matrix¶
This page lists every network flow of PKIFactor, so that you can write firewall rules and check what the platform does and does not do. It describes the appliance (single node and high availability); on Kubernetes and OpenShift the same application flows apply, and the cluster provides the entry point and the database.
No outbound flow by default
A fresh installation opens no connection outside the host: no online license check, no telemetry, no update check. Every outbound flow below exists only once you configure the matching item (an authority, a deployment target, a directory, an SMTP server...), and stops when you remove it.
How to read the tables:
| Column | Meaning |
|---|---|
| Direction | Inbound: towards the PKIFactor host. Outbound: from the PKIFactor host to one of your systems or to the Internet. Internal: inside the host's Docker network, never on your network. |
| Port | The default value. Where a port is set in a form or a variable, the table says so. |
| Required | Always: active from installation. Optional: only when the feature is configured. |
Architecture in brief¶
A single entry point, nginx, terminates TLS on ports 443 and 80 and relays to containers that are not published on the host: the web interface (8080), the API (8000), the ACME (8001), EST (8002), CMP (8003) and SCEP (8004) gateways, and the PostgreSQL database (5432), reachable only by those containers. A worker container (same image as the API) runs the background jobs: renewals, notifications, revocation monitoring, scans, deployment verification. Both the API and the worker open the outbound flows below.
Inbound flows¶
Users, API clients and enrollment¶
| Source | Destination | Port | Purpose | Required |
|---|---|---|---|---|
| Browsers, API clients | nginx, CLM name | 443/TCP (HTTPS) | Web interface, REST API (/api/ and /api/v1/), single sign-on callback (/sso/), health probes (/health/live, /health/ready). An optional client certificate (mTLS) is requested when a CA chain is installed |
Always |
| Anyone | nginx, CLM name | 80/TCP (HTTP) | Redirection to HTTPS, and the ACME HTTP-01 webroot (/.well-known/acme-challenge/) |
Always |
| ACME clients (certbot, acme.sh, win-acme, cert-manager...) | nginx, ACME name | 443/TCP | ACME server (RFC 8555), under /acme/<path>/ |
Optional: ACME gateway enabled |
| ACME clients | nginx, ACME name | 80/TCP | HTTP-01 webroot, redirection to HTTPS | Optional: ACME gateway enabled |
| Devices, servers | nginx, EST name | 443/TCP, client certificate optional | EST (RFC 7030), under /.well-known/est/ |
Optional: EST gateway enabled |
| Devices | nginx, CMP name | 443/TCP, and 80/TCP served directly (no redirection, as allowed by RFC 6712) | CMP (RFC 4210, RFC 9483), under /cmp/<path> |
Optional: CMP gateway enabled |
| Devices | nginx, SCEP name | 443/TCP, and 80/TCP served directly (as allowed by RFC 8894) | SCEP, under /scep/<path> |
Optional: SCEP gateway enabled |
| ServiceNow (a MID Server in your network, or the instance) | nginx, CLM name | 443/TCP | Certificate requests from the ServiceNow catalogue (ServiceNow) | Optional: ServiceNow inbound API enabled |
| Administrators | Host | 22/TCP (SSH) | Administration with pkifactor-ctl |
Recommended |
The host ports 80 and 443 can be changed with NGINX_HTTP_PORT and NGINX_HTTPS_PORT in .env (inside the container nginx listens on 8080 and 8443).
The ACME, EST, CMP and SCEP gateways exist only when their service is started and their variable (ACME_ENABLED, EST_ENABLED, CMP_ENABLED, SCEP_ENABLED) is true: otherwise there is no container and no virtual host for them. See Requirements for the DNS names.
Ports published by the gateways themselves¶
| Port | Service | Single node | High availability |
|---|---|---|---|
| 8003/TCP | CMP over HTTP, direct | Bound to 127.0.0.1 only |
Bound to 127.0.0.1 on a single-host cluster; published on the node address (HA_NODE_IP) with one node per host |
| 5683/UDP | CMP over CoAP (RFC 9482) | Bound to 127.0.0.1 only |
Bound to 127.0.0.1 on a single-host cluster; published on the node address (HA_NODE_IP) with one node per host |
| 8004/TCP | SCEP over HTTP, direct | Bound to 127.0.0.1 only |
Bound to 127.0.0.1 on a single-host cluster; published on the node address (HA_NODE_IP) with one node per host |
Devices normally reach CMP and SCEP through nginx (443 or 80). Publish 5683/UDP explicitly if your devices use CMP over CoAP.
Port 80
When the ACME gateway is enabled, its port 80 server is the default one: any plain HTTP request whose name matches no other server lands there (HTTP-01 webroot, otherwise redirected to the ACME name). CMP and SCEP are also answered in clear text on port 80. If you do not use HTTP-01, CMP over HTTP or SCEP over HTTP, restrict or close port 80 at your firewall.
Internal flows¶
These flows stay inside the host's Docker network; they need no firewall rule.
| Source | Destination | Port | Purpose |
|---|---|---|---|
| nginx | frontend | 8080/TCP | Web interface |
| nginx | backend | 8000/TCP | API, single sign-on, health |
| nginx | acme, est, cmp, scep | 8001, 8002, 8003, 8004/TCP | Protocol gateways |
| frontend | backend | 8000/TCP | Every call of the interface |
| backend, worker, gateways | PostgreSQL | 5432/TCP (6432 through PgBouncer in high availability) | Database |
| Gateways | backend | 8000/TCP | Profile resolution, issuance, revocation |
| nginx | Docker DNS (127.0.0.11) | 53/UDP | Container name resolution |
| Each container | itself | loopback | Docker health checks |
Outbound flows¶
Certification authorities¶
| Destination | Port | Purpose | Required |
|---|---|---|---|
| HashiCorp Vault PKI | HTTPS, the port of the address you enter (Vault's default is 8200) | Issuance, revocation, role synchronization, AppRole secret rotation | Optional: Vault authority configured |
| Microsoft AD CS | 5986/TCP (WinRM over HTTPS); 5985/TCP if HTTPS is turned off | Issuance and revocation through remote PowerShell | Optional: AD CS authority configured |
| EJBCA, ZetaCA, step-ca, Keyfactor, other REST CAs | HTTPS, the address you enter (no host is built in) | Issuance, revocation, template synchronization | Optional: authority configured |
| Upstream CA over CMP | HTTP or HTTPS, the endpoint you enter | CMP relay to an upstream CA | Optional: CMP authority configured |
| DigiCert CertCentral | 443/TCP, www.digicert.com |
Public CA: order, collect, revoke | Optional |
| DigiCert ONE | 443/TCP, one.digicert.com (API key) or clientauth.one.digicert.com (client certificate) |
Public CA | Optional |
| Sectigo | 443/TCP, secure.trust-provider.com; for Sectigo Certificate Manager, auth.sso.sectigo.com and the admin.<instance>.sectigo.com of your instance |
Public CA | Optional |
| Public ACME CAs | 443/TCP: Let's Encrypt, ZeroSSL, Sectigo ACME, Google Trust Services | Issuance through a public ACME CA | Optional: upstream ACME account configured |
An outbound proxy can be set for all HTTPS (HTTPS_PROXY, NO_PROXY) or per authority (Requirements).
Domain validation and DNS¶
| Destination | Port | Purpose | Required |
|---|---|---|---|
| Public resolvers 8.8.8.8, 1.1.1.1, 9.9.9.9, 208.67.222.222 | 53/UDP and TCP | TXT and CAA checks during domain validation (an answer agreed by several resolvers is required) | Optional: public CA or upstream ACME issuance |
| Authoritative name servers of the zone | 53/UDP and TCP | Authoritative resolution | Same |
DNS provider APIs: OVH, Azure DNS (login.microsoftonline.com, management.azure.com), Cloudflare, Gandi, Google Cloud DNS, your own webhook |
443/TCP | Placing TXT records for DNS-01 and domain validation | Optional: DNS provider configured |
ACME gateway challenge validation¶
| Source | Destination | Port | Purpose | Required |
|---|---|---|---|---|
| acme | Host named in the ACME order | 80/TCP | HTTP-01 validation, without following redirections | Optional: HTTP-01 challenge |
| acme | Host named in the ACME order | 443/TCP | TLS-ALPN-01 validation | Optional: TLS-ALPN-01 challenge |
| acme | DNS resolvers (ACME_DNS_RESOLVERS, or the system resolver) |
53/UDP and TCP | DNS-01 validation, CAA check | Optional: DNS-01 challenge, CAA |
For HTTP-01, private addresses are refused as validation targets unless you allow internal networks in the ACME settings. The EST, CMP and SCEP gateways open no flow outside the host.
Deployment targets¶
No agent is installed on devices or servers: PKIFactor uses their management API or SSH, from the backend and worker containers.
| Destination | Port | Purpose | Required |
|---|---|---|---|
| F5 BIG-IP, management address | 443/TCP: iControl REST and iControl SOAP | Import, binding, verification, following the active unit (F5 BIG-IP) | Optional |
| FortiWeb, management address | 443/TCP | Import, binding, verification (FortiWeb) | Optional |
| Palo Alto Networks PAN-OS or Panorama, management interface | 443/TCP (XML API) | Import, commit (Palo Alto Networks) | Optional |
| Check Point Security Management server | 443/TCP, port editable on the target | Import, publish, policy installation (Check Point) | Optional |
| Kemp LoadMaster, management address | 443/TCP | Import, binding (Kemp) | Optional |
| Windows server with IIS | 5986/TCP (WinRM over HTTPS) | Import into the certificate store, IIS binding (Windows and IIS) | Optional |
| Linux server | 22/TCP (SSH and SFTP), port set per target | File delivery, service reload, inventory (SSH servers) | Optional |
| TLS service of each SSH site | The probe port of the site (for example 443, 8443) | Reading the certificate actually served after deployment and at each verification | Optional: SSH target with a probe |
| Health URL of an SSH site | HTTPS, the port of the URL (443 by default) | Post-reload health check; on failure the previous certificate is restored | Optional: health URL set |
Directories and single sign-on¶
| Destination | Port | Purpose | Required |
|---|---|---|---|
| LDAP or Active Directory | 636/TCP (LDAPS), or 389/TCP (plain or StartTLS); port editable | Directory groups, people search | Optional: LDAP source configured |
| Microsoft Entra ID | 443/TCP, login.microsoftonline.com and graph.microsoft.com |
Directory groups through Microsoft Graph | Optional |
| Keycloak, Okta | 443/TCP, the address you enter | Directory groups | Optional |
| Google Workspace | 443/TCP, oauth2.googleapis.com and admin.googleapis.com |
Directory groups | Optional |
| SCIM server | 443/TCP, the SCIM base URL you enter | Directory groups | Optional |
| OIDC identity provider (Keycloak, Entra ID, Okta...) | 443/TCP: token, JWKS, user information (the endpoints are entered on the provider; PKIFactor does not fetch the discovery document) | Single sign-on. HTTPS is mandatory towards the provider | Optional: SSO provider configured |
Key management¶
| Destination | Port | Purpose | Required |
|---|---|---|---|
| HashiCorp Vault Transit | HTTPS, the port of the Vault address (8200 by default on Vault) | Wrapping and unwrapping of the data keys, from the backend, the worker and the ACME and EST gateways (KMS and HSM) | Optional: vault-transit provider |
| Network HSM | The vendor port, set in the PKCS#11 library configuration (for example 3001/TCP for Utimaco CryptoServer) | Key wrapping in the HSM | Optional: pkcs11-hsm provider |
Operations and integrations¶
| Destination | Port | Purpose | Required |
|---|---|---|---|
| SMTP server | 587/TCP with STARTTLS by default, or 465/TCP (SMTPS); port editable | Notifications and expiry notices | Optional |
| SIEM | 514/UDP by default; TCP or TCP with TLS (mutual TLS possible); port editable | Audit trail forwarding in CEF or RFC 5424 (SIEM) | Optional: SIEM forwarding enabled |
| ServiceNow instance | 443/TCP, https://<instance>.service-now.com, directly or through your proxy |
Inventory, incidents and changes, ticket feedback (ServiceNow) | Optional |
| SFTP backup server | 22/TCP, port editable | Copy of the scheduled backups (Backup and restore) | Optional: SFTP storage |
| CRL distribution points, OCSP responders | HTTP or HTTPS | Revocation monitoring of each authority, on-demand revocation check | Optional: as soon as an authority publishes a CRL or OCSP |
| Issuer AIA URLs | HTTP or HTTPS, redirections not followed | Chain building at certificate import | Optional |
| Scan targets | TLS on 443 and 8443 (quick); also 636, 993, 995, 465, 587, 25, 143, 110, 21, 389, 8080, 8444, 9443, 4443 (standard), with STARTTLS where the protocol uses it; or your own ranges | Discovery of certificates in service (TLS scanning) | Optional: scan started |
| Certificate Transparency sources | 443/TCP: crt.sh, api.certspotter.com, or the address you enter; a CertStream server of your own over WebSocket (wss://) for the real-time feed; directly or through the proxy set on the source |
Certificate Transparency monitoring of your domains (Certificate Transparency) | Optional: CT source configured |
| Other high-availability nodes | 443/TCP | Rolling restart started by an administrator | Optional: high availability |
Revocation and AIA requests to private addresses are blocked unless you allow the internal networks on the authority (field Allowed internal networks (revocation)). Loopback, link-local and multicast addresses are always refused.
Time and name resolution¶
PKIFactor has no NTP client of its own: the containers use the clock of the host. Synchronize every host with NTP (Requirements). Host names that you enter in forms (authorities, targets, directories) are resolved through the host's DNS configuration.
High availability¶
These flows exist only in a high-availability installation (High availability). On each node they are bound to the node address (HA_NODE_IP).
| Source | Destination | Port | Purpose |
|---|---|---|---|
| Nodes, witness | Every etcd member (nodes and witness) | 2379/TCP (client), 2380/TCP (peer), mutual TLS | etcd consensus used by Patroni |
| Nodes | Other nodes | 5432/TCP | PostgreSQL replication |
| Nodes | Other nodes | 8008/TCP | Patroni REST API (leader election, health) |
| Load balancer | Every node | 443/TCP (and 80/TCP for HTTP-01, CMP or SCEP over HTTP) | Client traffic; health check GET /health/ready |
| Nodes | Other nodes | 443/TCP | Rolling restart from the interface (verified with HA_PEER_CA) |
PgBouncer (6432) listens only inside each node's Docker network. The witness publishes 2379 and 2380 on all its interfaces: filter them to the node addresses.
What PKIFactor never does¶
| Flow | Status |
|---|---|
| Online license check | None: the license signature is verified locally (License) |
| Sending the license request | Manual: you copy the request block from System > License (Administration workspace) or pkifactor-ctl license request and send it to ZetaCert |
| Telemetry, crash reporting, update check | None |
| External resources in the browser (CDN, fonts) | None: scripts, styles and fonts are served by the platform itself, and the content security policy limits scripts, fonts and connections to the platform |
Minimal firewall rules¶
- Inbound: 443/TCP from workstations, API clients and enrolling devices; 80/TCP only for HTTP-01, CMP or SCEP over HTTP; 22/TCP from administration workstations.
- Outbound: only the destinations of what you configured, each on its port above.
- High availability: 2379, 2380, 5432 and 8008/TCP between the nodes and the witness only.
Everything else can be denied with no effect on the platform.
Check it yourself¶
On the PKIFactor host:
ss -ltnup | grep -E 'docker|nginx' # listening ports
docker compose -f /opt/pkifactor/docker-compose.yml ps --format '{{.Name}} {{.Ports}}'
To list the connections that leave the Docker network, capture for a few hours (the revocation monitor, for example, runs every 30 minutes):
tcpdump -ni any 'src net 172.16.0.0/12 and not dst net 172.16.0.0/12 and not dst net 127.0.0.0/8'
On a fresh installation with nothing configured, the capture stays empty. Each item you configure then adds only its own flow.