W Watchflare docs

TLS certificates

How the Hub manages TLS for agent communication, and how to bring your own certificates.

The Hub uses TLS 1.3 for all agent↔Hub communication on the gRPC port (50051). Two modes are available: auto (default) and custom.


Auto mode (default)

With TLS_MODE=auto, the Hub generates a self-signed Certificate Authority (CA) and a server certificate on first startup. They are stored in the pki_data Docker volume and reused on every subsequent start.

pki_data/
├── ca.pem       # CA certificate — sent to agents at registration
├── ca.key       # CA private key
├── server.pem   # Server certificate, signed by the CA
└── server.key   # Server private key

Both certificates use ECDSA P-256 keys.

CertificateCNValidity
CAwatchflare CA10 years
Serverwatchflare5 years

At registration, the Hub sends the CA certificate to the agent. The agent pins it for all future connections — no manual certificate distribution needed. On Linux it is saved to /etc/watchflare/ca.pem; on macOS to $(brew --prefix)/etc/watchflare/ca.pem.

Warning

In auto mode, the Hub regenerates both the CA and the server certificate together. There is no way to renew the server certificate alone. If you remove server.pem to force a renewal, the CA will also be replaced and all registered agents must be re-registered.


Custom mode

With TLS_MODE=custom, the Hub uses your own certificates. This is useful if you have an existing internal PKI.

Add these variables to your .env:

.env bash
TLS_MODE=custom
TLS_CERT_FILE=/certs/server.pem
TLS_KEY_FILE=/certs/server.key
TLS_CA_FILE=/certs/ca.pem

Mount your certificate directory into the Hub container:

docker-compose.yml yaml
services:
  watchflare:
    volumes:
      - pki_data:/var/lib/watchflare/pki
      - /etc/ssl/watchflare:/certs:ro

Requirements

  • TLS_CA_FILE must be the CA that signed TLS_CERT_FILE. This CA is returned to agents at registration and pinned on their side.
  • TLS 1.3 is mandatory — the Hub rejects connections below this version regardless of mode.
  • The server certificate CN does not need to match the Hub’s hostname. It must match the tls_server value in agent.conf (default: watchflare). Using HostSNI("*") on your reverse proxy avoids any CN mismatch — see Reverse proxy.

Warning

If you replace the CA after agents have registered, those agents will reject the new certificate — their pinned CA no longer matches. You will need to re-register each affected agent.


Inspecting certificates

To inspect the auto-generated certificates from inside the container:

bash
docker exec watchflare openssl x509 -in /var/lib/watchflare/pki/ca.pem -noout -text
docker exec watchflare openssl x509 -in /var/lib/watchflare/pki/server.pem -noout -text

The gRPC port and reverse proxies

The gRPC port (50051) must not be TLS-terminated by a reverse proxy. Agents pin the Hub’s CA — any certificate from a different CA is rejected. Configure your proxy for TCP passthrough. See Reverse proxy.