This is the multi-page printable view of this section. .
Self-Cert
Why self-sign
Two addons that speak S3 over TLS — minio,
silo, rustfs — can serve certificates
two ways:
- Generated (
--tls): pgcli mints a self-signed CA + leaf for you, owns the cert dir, and refreshes it on restart. Zero setup, fixed SANs. - Bring-your-own (
--tls-cert/--tls-key): you supply the pair. This is where a public CA cert, a wildcard you already hold, or a cert with custom SANs goes.
pg cert is the mint for the second path: it creates a self-signed certificate
whose SANs cover exactly the hostnames and IPs you need, so you can try BYO TLS
without a real CA — and it writes them as a standalone pair, not registered
with pgcli: the files go wherever you point them, pg.yaml is untouched, and
no container is started. Hand them to a store with --tls-cert/--tls-key
yourself.
Quick start
pg cert prints the SANs it wrote and nothing else — it is a pure file
generator, not an addon command.
Flags
| Flag | Default | Meaning |
|---|---|---|
--host |
127.0.0.1 |
Comma-separated DNS names and/or IPs to encode as SANs (repeatable). Entries are auto-detected as one or the other, so "rustfs.test,10.0.0.9" needs no special syntax; *.wild.test works as a wildcard DNS entry. |
--cert-file |
cert.pem |
Path to write the PEM certificate. |
--key-file |
key.pem |
Path to write the PEM private key (PKCS8, mode 0600). |
--valid-duration |
825 days |
How long the cert stays valid, e.g. --valid-duration 8760h for a year. |
--ecdsa |
P-256 |
Curve: P-224/P-256/P-384/P-521. Set to "" to disable ECDSA (and pair with --rsa). |
--rsa |
(off) | RSA key size (e.g. 2048, 4096); set only when you specifically need RSA instead of the default ECDSA key. |
--ca |
false |
Make the cert its own CA (CA:TRUE, keyCertSign) — for when you want a private root to sign further certs with, not the usual case for --tls-cert. |
The same generator is built as a standalone binary for use outside pg —
make gencert → bin/gencert, with the identical flag set in single-dash form
(-host, -cert-file, …). Both front one package, so their output is the same
kind of certificate byte-for-byte.
What pg cert writes
One self-signed leaf, not a chain. The PEM in --cert-file holds exactly one
CERTIFICATE block — the cert signs itself (CA:FALSE, serverAuth EKU, your
SANs). There is deliberately no leaf+intermediate+root bundle: there is no
issuing CA above it, so there is nothing to chain.
This is also why the --ca output is not something to point --tls-cert
at: pg addon install … --tls-cert runs ValidateBYOCert, which inspects the
first certificate and rejects one that is a CA. The --ca cert is a trust
anchor you sign others with, not a server cert to serve.
Using it as the client’s trust anchor
Because the result is self-signed, hand the same .crt to every TLS client as
its CA file — the served leaf is its own trust anchor. For pgBackRest’s S3
repository that means pointing --s3-ca-file at the pg cert output directly:
This is not a workaround pgBackRest merely tolerates: OpenSSL treats whatever
you hand it as an anchor (CA:TRUE not required), and pgBackRest’s S3 TLS path
is that same mechanism. Verified directly: openssl verify -CAfile <cert> <cert>
on the self-signed CA:FALSE leaf returns OK.
To place the cert on a host that dials the store without shipping the file, use
pg backup fetch-ca — it pulls the
issuing cert straight out of the live TLS handshake.
Serving it from a store
The three S3 stores each mount your pair under the filenames their binary
requires, so your filenames are free — pg cert --cert-file anything.crt
works for all three:
pgcli never re-owns or writes to your source files; in rustfs’s case the pair is mounted read-only and copied into the container’s own cert dir (see rustfs → Privileges and ownership).
Verified on rustfs
On a real install, a pg cert leaf served by rustfs was confirmed off the live
TLS handshake (subject == issuer on the cert actually presented, not just what
pg.yaml recorded), the container came up healthy over HTTPS, and pg mc
completed a full alias set → mb → put → ls → get round-trip against it
with the fetched object byte-identical to the one uploaded.
Renewing a BYO cert
A single-file bind mount pins the source inode, so replacing the file in place does not take effect on a running container. To renew, mint a fresh pair (or overwrite the files), then recreate:
Turning BYO off (fall back to the generated pair, or plain HTTP): delete the
cert_file/key_file lines for that addon in pg.yaml and --force a
recreate.
See also
minio·silo·rustfs— each has a “Bring your own certificate” section- Backup → S3 object storage repository
— the
--s3-ca-file/fetch-caclient side