# Certificates

> Hot-swap the gateway's TLS material without dropping connections.

The QUIC and WebTransport listeners terminate TLS with a cert/key pair on
disk. `ReloadCertificates` reloads the pair in place. Use it for ACME/Let's
Encrypt renewals, or to rotate compromised material without a restart.

> **WARNING:**
> There is no SDK wrapper. Use the [raw RPC envelope](/rpc/envelope-format) to call this method.

## `ReloadCertificates`

Request (`ReloadCertificatesRequest`):

| Field        | Type     | Notes                                                        |
| ------------ | -------- | ------------------------------------------------------------ |
| `cert_path`  | `string` | Absolute path on the gateway host to the new PEM cert chain. |
| `key_path`   | `string` | Absolute path to the matching PEM private key.               |

Both files must already exist on the gateway's filesystem at the supplied
paths. The admin RPC does not transport file bytes. It only starts an
in-process reload.

Response (`ReloadCertificatesResponse`):

| Field           | Type     | Notes                                          |
| --------------- | -------- | ---------------------------------------------- |
| `status`        | `string` | `"ok"` on success; `"error"` otherwise.        |
| `error_message` | `string` | Populated when `status="error"` (e.g. parse failure, mismatched key). |

## What changes when

- **Existing QUIC connections** keep their session tickets. They continue
  to use the certificate from their handshake. The gateway does not drop
  them.
- **New QUIC handshakes** use the newly loaded cert. The next 0-RTT
  resumption that crosses a TLS context refresh also uses it.
- **Self-signed dev certs**: browsers cache `serverCertificateHashes`. If
  you rotate a self-signed cert, pass the new fingerprint through the SDK
  constructor in every browser tab.

## ACME loop

A typical operator setup runs `certbot renew` on a cron schedule. It then
calls `ReloadCertificates`:

```
certbot renew --quiet --post-hook \
  '<your-rpc-client> ReloadCertificates \
     --cert /etc/letsencrypt/live/engine.firstbyte.fast/fullchain.pem \
     --key  /etc/letsencrypt/live/engine.firstbyte.fast/privkey.pem'
```

`<your-rpc-client>` is the raw QUIC client that you build to drive the
admin RPC. By design, the SDK gives no help here.

## Failure mode

If the new cert/key pair fails validation, the gateway keeps the old
material and returns `status="error"`. There is no half-loaded state.
