Skip to content

Agent mTLS

Every dockmesh server is its own private certificate authority. When you enrol an agent, the server issues it a client certificate; the agent presents that cert on every connection and the server validates it against its own CA.

  • No public CA — agents don’t need internet access to verify certs
  • Revocable per-agent — mark an agent revoked and the next handshake is rejected
  • Simple ops — one trust root per server, backed up with the data directory

The CA lives on disk in the dockmesh data directory, next to the database:

FileModeContents
agents-ca.crt0644CA certificate (ECDSA P-256, valid 10 years)
agents-ca.key0400CA private key
agents-server.crt / agents-server.key0644 / 0400Server cert for the mTLS listener, valid 5 years

Protect the data directory with standard filesystem permissions — the CA key is not additionally encrypted. A backup of the data directory includes the CA and restores the fleet’s trust relationship; losing it requires re-enrolling every agent.

When you add an agent from Agents → New agent, the server generates a one-time enrolment token (a bearer string, not a certificate). You run dockmesh-agent on the target host with that token as an argument. On first connect:

  1. The agent calls the server’s enrolment endpoint with the token.
  2. The server validates the token against the pending agent row.
  3. The server issues a long-term client certificate signed by its CA, with the agent’s UUID as the Common Name. SANs include the hostnames / IPs configured via DOCKMESH_AGENT_SANS on the server.
  4. The enrolment token is invalidated — one-time use.

From that point on, the agent authenticates every WebSocket connection with its cert.

Client certs are issued with a 1-year validity. There is no auto-renewal yet — long-running agents will need a manual rotation before expiry, which you can do from Agents → select agent → Rotate enrolment token followed by re-enrolment on the host. An agent whose cert expires will see handshake failures and mark itself offline; no silent breakage.

Cert renewal before expiry is planned for a follow-up release.

Agents → select agent → Revoke marks the agent’s row as revoked. On the next handshake the server refuses the connection with 403 agent revoked; the agent exits cleanly. There is no CRL polling delay — the check happens against the database on every connection attempt.

The HTTP listener (UI and REST API) and the agent mTLS listener are separate:

  • UI / REST (:8080) — plain HTTP by default; put it behind a reverse proxy (Caddy, Traefik, nginx) for TLS, or enable the embedded Caddy to get auto-HTTPS via Let’s Encrypt.
  • Agent mTLS (:8443) — uses the server’s self-issued agents-server.crt automatically. Agents pin the server CA in their config, so no public trust is required.

Extra hostnames or IPs for the server cert come from DOCKMESH_AGENT_SANS (comma-separated).