# CertManager

Network communication in production systems needs encryption. TLS provides this, but managing TLS certificates introduces operational challenges. Certificates expire. Security incidents require rotation. Updating certificates traditionally means restarting services, causing downtime.

The naive approach loads certificates at startup from files. When you need to update a certificate, you replace the file and restart the service. For a single service, this works. For distributed systems with dozens of nodes and services, coordinating restarts for certificate updates becomes an operational burden.

Ergo Framework provides `gen.CertManager` for live certificate updates. Load a certificate at startup, and you can update it later without restarting. All components using that certificate manager - node acceptors, web servers, TCP servers - automatically use the updated certificate for new connections.

## Creating a Certificate Manager

Create a certificate manager with an initial certificate:

```go
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
if err != nil {
    panic(err)
}

certManager := gen.CreateCertManager(cert)
```

For development or testing, generate a self-signed certificate:

```go
cert, err := lib.GenerateSelfSignedCert("MyService v1.0")
if err != nil {
    panic(err)
}

certManager := gen.CreateCertManager(cert)
```

Note: Self-signed certificates require setting `InsecureSkipVerify: true` in network options to bypass certificate validation. This is acceptable for development but never use it in production.

Pass the certificate manager to node options:

```go
options.CertManager = certManager
node, err := ergo.StartNode("node@localhost", options)
```

The node's network stack uses this certificate manager for TLS connections. Acceptors use it for incoming connections. Outgoing connections use it for client certificates if needed.

## Updating Certificates

Update the certificate while the node is running:

```go
newCert, err := tls.LoadX509KeyPair("new_cert.pem", "new_key.pem")
if err != nil {
    return err
}

certManager.Update(newCert)
```

The update takes effect immediately for new connections. Existing connections continue using the old certificate until they close. This allows graceful rotation - new connections get the new certificate, old connections finish naturally.

Components using the certificate manager obtain certificates through `GetCertificate` or `GetCertificateFunc`. These methods return the current certificate, so updates automatically propagate to all users of the manager.

## Certificate Lifecycle

The typical pattern involves periodic certificate renewal. A cron job or external process watches for approaching expiration. When renewal is needed, it obtains a new certificate (from Let's Encrypt, an internal CA, or however your infrastructure manages certificates) and calls `Update` on the certificate manager.

The certificate manager is passive - it doesn't handle renewal itself. It provides the mechanism for live updates. Your renewal logic is external, allowing integration with whatever certificate provisioning system you use.

This separation is intentional. Certificate renewal policies vary widely. Some organizations use Let's Encrypt with automated renewal. Others use internal CAs with manual processes. Some rotate certificates on a schedule, others only when necessary. The certificate manager doesn't impose policy - it just enables live updates however you choose to implement them.

## Mutual TLS

For scenarios requiring client certificate authentication, use `gen.CertAuthManager`. It extends `CertManager` with CA pool management for verifying certificates on both sides of the connection. This enables mutual TLS (mTLS) where servers verify client certificates and clients verify server certificates.

```go
certManager := gen.CreateCertAuthManager(cert)
certManager.SetClientCAs(clientCAPool)    // server verifies clients
certManager.SetRootCAs(serverCAPool)      // client verifies servers
certManager.SetClientAuth(tls.RequireAndVerifyClientCert)
```

All settings support runtime updates, just like certificate rotation.

For detailed configuration and examples, see [Mutual TLS](/networking/mutual-tls.md).

For complete certificate manager methods and usage, refer to the `gen.CertManager` interface documentation in the code.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ergo.services/basics/certmanager.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
