> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nanny.run/llms.txt
> Use this file to discover all available pages before exploring further.

# nanny certs

> Generate, import, rotate, inspect, and remove TLS certificates for the Nanny governance server.

TLS certificates are required when the governance server binds to a non-loopback address (anything outside `127.x.x.x`). For local multi-process development on loopback, no certs are needed.

```bash theme={null}
nanny certs <COMMAND>
```

***

## Commands

### generate

Generate a complete certificate bundle for the governance server.

```bash theme={null}
nanny certs generate [--out-dir <path>] [--days <days>] [--force]
```

Always generates all six files atomically, PKI requires a CA to sign the server and client certs, so partial generation is not supported.

#### Files generated

```
~/.nanny/certs/
  ca.crt      CA certificate (the trust anchor)
  ca.key      CA private key (keep this on the server machine; needed for nanny certs rotate)
  server.crt  server TLS certificate
  server.key  server TLS private key
  client.crt  client certificate (copy to each agent machine)
  client.key  client private key (copy to each agent machine)
```

`nanny run --serve` reads `server.crt`, `server.key`, and `ca.crt` automatically. Agents on other machines need `client.crt`, `client.key`, and `ca.crt`.

#### Flags

| Flag        | Type    | Default           | Description                                                                                                            |
| ----------- | ------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `--out-dir` | path    | `~/.nanny/certs/` | Directory to write cert files. The default is outside any project directory so files are never accidentally committed. |
| `--days`    | integer | `365`             | Certificate validity period in days.                                                                                   |
| `--force`   | flag    | —                 | Overwrite existing cert files. Without this flag, `generate` refuses if any cert files already exist.                  |

#### Example output

```
nanny certs: generated certificate bundle in '/Users/you/.nanny/certs'

  ca.crt      CA certificate
  ca.key      CA private key    (keep secure, used for rotate)
  server.crt  server certificate
  server.key  server private key
  client.crt  client certificate (distribute to agents)
  client.key  client private key  (distribute to agents)

  valid until: 2027-05-01T09:00:00Z

Start the server:
  nanny run --serve

Cross-machine agents: copy client.crt + client.key to each agent machine
and set NANNY_BRIDGE_CERT, NANNY_BRIDGE_KEY, NANNY_BRIDGE_CA in the env.
```

#### If cert files already exist

```
cert bundle already exists at '/Users/you/.nanny/certs'

To keep your CA and regenerate only the server + client certs:
  nanny certs rotate    , regenerate server + client certs, keep CA
To inspect what you have:
  nanny certs show      , inspect current expiry
To regenerate everything (new CA, new server cert, new client cert):
  nanny certs generate --force
```

***

### import

Import externally-issued certificates. Use this when your organization has its own PKI (HashiCorp Vault, AWS ACM, cert-manager, an internal CA).

```bash theme={null}
nanny certs import [ca=<pem|@file>] [cert=<pem|@file>] [key=<pem|@file>]
```

Takes `key=value` pairs. Values are either a PEM string or a `@file` reference (path prefixed with `@`). Three keys are accepted: `ca`, `cert`, `key`.

**Partial imports are supported.** Omit any key to leave the existing file unchanged. This is useful for rotating only the server cert and key while keeping the existing CA:

```bash theme={null}
nanny certs import cert=@new-server.crt key=@new-server.key
```

After any import, Nanny validates that the certificate is signed by the CA (imported or existing). A mismatched cert/CA pair fails loudly with a clear error before any file is written.

#### Examples

**From files:**

```bash theme={null}
nanny certs import \
  ca=@/vault/secrets/ca.pem \
  cert=@/vault/secrets/tls.crt \
  key=@/vault/secrets/tls.key
```

**From environment variables (Vault Agent, CI/CD injection):**

```bash theme={null}
nanny certs import \
  ca="$VAULT_CA" \
  cert="$VAULT_CERT" \
  key="$VAULT_KEY"
```

**Directly from Vault CLI (no temp files):**

```bash theme={null}
nanny certs import \
  ca="$(vault read -field=issuing_ca pki/cert/ca)" \
  cert="$(vault read -field=certificate pki/issue/nanny-server)" \
  key="$(vault read -field=private_key pki/issue/nanny-server)"
```

**Updating CA, cert, and key together (CA was replaced by external PKI):**

```bash theme={null}
nanny certs import \
  ca=@new-ca.crt \
  cert=@new-server.crt \
  key=@new-server.key
```

After a successful import, if the governance server is running, it hot-reloads the new certs automatically. No restart needed.

***

### rotate

Regenerate the server and client certificates, preserving the existing CA.

```bash theme={null}
nanny certs rotate
```

`rotate` signs new server and client certs using the CA that `nanny certs generate` created. The CA itself is not changed, existing agents that trust this CA continue to work without re-importing `ca.crt`.

**When to use `rotate`:**

* Cert expiry is approaching (check with `nanny certs show`)
* You want to invalidate the existing client cert (rotation generates a new `client.crt` + `client.key`)

**When `rotate` does not apply:**

* Your certs were issued by an external PKI (Vault, AWS ACM, etc.), those systems hold the CA private key, not Nanny. Use `nanny certs import` instead.

`rotate` requires `ca.key` to be present in `~/.nanny/certs/`. This file only exists when `nanny certs generate` created the CA. If `ca.key` is missing, `rotate` exits with an error and suggests `nanny certs import`.

#### Example output

```
nanny certs: rotated, server + client certs regenerated, CA preserved
  valid until: 2027-05-01T09:00:00Z

  CA unchanged, existing agents retain their trust anchor
  Redistribute client.crt + client.key to agents on other machines

nanny certs: server is running, certs will hot-reload automatically
```

***

### show

Show expiry dates, file inventory, and SAN list for the current cert bundle.

```bash theme={null}
nanny certs show
```

Does not print private key material or file paths. Status only.

#### Example output

```
nanny certs: '/Users/you/.nanny/certs'

  expires : 2027-05-01T09:00:00Z
  san     : localhost, 127.0.0.1

  present    ca.crt
  present    ca.key
  present    server.crt
  present    server.key
  present    client.crt
  present    client.key
```

If no certs exist:

```
nanny certs: no certificates found, run `nanny certs generate`
```

***

### remove

Delete all cert files from `~/.nanny/certs/`.

```bash theme={null}
nanny certs remove
```

Prompts for confirmation before deleting. After removal, `nanny run --serve` with a non-loopback address will refuse to start until new certs are generated or imported.

**If no certs exist:**

```
nanny certs: nothing to remove, '/Users/you/.nanny/certs' does not exist
```

***

## Certificate hot-reload

The governance server watches `~/.nanny/certs/` for file changes. When cert files are updated, by `nanny certs import`, `nanny certs rotate`, or an external PKI agent writing to the directory, the server reloads the new certs without restarting. New connections use the new cert immediately; existing connections complete on the old cert.

This is designed for short-lived PKI certs (for example, Vault PKI secrets engine issuing 8-hour certs renewed automatically by Vault Agent). The server stays up; certs rotate underneath it.

***

## Keeping `ca.key` secure

The CA private key (`ca.key`) is the trust anchor for your entire certificate bundle. Anyone with access to `ca.key` can generate new certificates that your server will accept.

* Keep `ca.key` on the server machine only. Never copy it to agent machines.
* The client machines need only `ca.crt` (to verify the server) and `client.crt` + `client.key` (to present to the server).
* Back up `ca.key` securely. If you lose it, run `nanny certs generate --force` to start fresh, but you will need to redistribute `ca.crt` to all agent machines.
