Skip to content

Add SIGHUP refresh path for CA pool and DKG client credentials #104

Description

@AntiD2ta

Context

SIGHUP currently reloads only the leaf server certificate via the dynamic GetCertificate callback. Two other pieces of TLS material are snapshotted at process start and stay frozen for the life of the process:

  1. ca-cert / client CA pool. NewServerTLSConfig populates tls.Config.ClientCAs from a []byte slice fetched once at startup (see services/api/grpc/service.go::createServer). Rotating ca.crt to add or revoke a client CA and sending SIGHUP refreshes the server cert but leaves the boot-time ClientCAs in place. Newly authorised clients fail to authenticate; revoked CAs keep working. The cluster ends up half-rotated with no operator-visible signal that a full restart is required.

  2. DKG client credentials. NewGRPCClientCredentials snapshots the client cert manager's tls.Config once at sender construction. That TransportCredentials value is closure-captured inside obtainConnection's puddle.NewPool constructor, so every cached pool keeps dialing peers with the original credentials. There is no path to refresh the outbound DKG identity — once the cert nears expiry, every handshake fails with "certificate has expired" while disk shows a valid replacement cert.

The operational consequence — "rotation requires a full Dirk restart, SIGHUP is not enough" — is now documented in docs/configuration.md, but documentation alone is a workaround, not a fix. A full restart drops every connected Vouch/validator and costs missed attestations.

Proposed refresh path

CA pool

Plumb tls.Config.VerifyPeerCertificate against a swappable *x509.CertPool held in an atomic.Pointer. Cert manager fires a reload hook → the pool is rebuilt from the fresh PEM → the next handshake reads the new pool through the verifier. Cleaner than rebuilding the tls.Config because verification happens per handshake; no connection teardown needed.

DKG client credentials

Harder. Requires draining the puddle connection pools and re-instantiating s.credentials once a new client cert is loaded. Gated on the client cert manager firing a reload hook (which today does not exist — the client cert manager has no SIGHUP wiring at all). Steps:

  1. Wire the client cert manager into the SIGHUP handler in main.go.
  2. Add a reload callback on the sender that swaps s.credentials and drains affected puddle pools.
  3. Confirm in-flight RPCs survive the drain.

Scope

One issue, two scopes (CA pool + DKG client credentials) — they share the "TLS material frozen at startup, no refresh path" root cause. Track separately if work splits naturally.

Refs

Follow-up to PR #91 (use-go-certmanager).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions