Create a private root certificate authority
To create a root CA, generate a key and a self-signed CA certificate with the CA basic constraint set — `openssl req -x509 -new -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3650 -subj "/CN=Example Internal Root CA" -addext "basicConstraints=critical,CA:TRUE" -addext "keyUsage=critical,keyCertSign,cRLSign"`. The `basicConstraints=CA:TRUE` extension is what makes it a CA rather than an ordinary self-signed certificate; without it nothing will accept certificates it signs. Encrypt the CA key with a passphrase, because anything holding it can issue certificates your machines will trust.
Step 1 — the CA private key #
Encrypt it. This is the one key where a passphrase is unambiguously correct, because a CA key is not read by an unattended service:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -aes-256-cbc -out ca.key chmod 400 ca.key Step 2 — the self-signed CA certificate #
openssl req -x509 -new -key ca.key -out ca.crt -days 3650 -sha256 \
-subj "/C=US/O=Example Inc/CN=Example Inc Internal Root CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash" Replace these values
| Placeholder | What to put there |
|---|---|
basicConstraints=critical,CA:TRUE | What makes this a CA. Marked critical so it cannot be ignored. |
keyUsage=critical,keyCertSign,cRLSign | Restricts the key to signing certificates and revocation lists. |
subjectKeyIdentifier=hash | Lets clients link issued certificates back to this CA reliably. |
-days 3650 | Ten years. Longer means fewer trust-store updates and a longer-lived risk. |
Step 3 — check what you built #
openssl x509 -in ca.crt -noout -subject -issuer -dates -ext basicConstraints -ext keyUsage Expected output
subject=C = US, O = Example Inc, CN = Example Inc Internal Root CA issuer=C = US, O = Example Inc, CN = Example Inc Internal Root CA notBefore=Aug 19 12:00:00 2026 GMT notAfter=Aug 17 12:00:00 2036 GMT X509v3 Basic Constraints: critical CA:TRUE X509v3 Key Usage: critical Certificate Sign, CRL Sign
Identical subject and issuer confirms it is self-signed — correct for a root. CA:TRUE confirms it
can sign. If CA:TRUE is missing, start again; certificates signed by this will be rejected and the
error will not obviously point back here.
Step 4 — distribute the CA certificate #
Install ca.crt — never ca.key — on every machine that needs to trust what you issue:
sudo cp ca.crt /usr/local/share/ca-certificates/example-internal-ca.crt
sudo update-ca-certificates sudo cp ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust extract sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain ca.crt sudo apk add ca-certificates
sudo cp ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates Step 5 — issue your first certificate #
openssl req -new -newkey rsa:2048 -nodes \
-keyout server.key -out server.csr \
-subj "/CN=service.internal" \
-addext "subjectAltName=DNS:service.internal,DNS:*.service.internal" openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 397 -sha256 \
-copy_extensions copyall Why a CA beats self-signed certificates #
| Self-signed | Private CA | |
|---|---|---|
| Trust-store operations | One per certificate, per machine | One per machine, ever |
| Renewals | Re-trust every time | Just reissue |
| Revocation | None | Possible via CRL |
| Effort for 1 certificate | Lower | Higher |
| Effort for 5+ certificates | Much higher | Much lower |
Frequently asked questions
- What makes a certificate a CA certificate?
- The
basicConstraintsextension containingCA:TRUE, marked critical. Without it, a certificate is an ordinary end-entity certificate and every correct implementation will refuse to accept signatures it makes on other certificates. - How long should a root CA last?
- Ten years is typical for an internal root, because replacing it means touching the trust store on every machine again. The trade-off is that a long-lived root is a long-lived liability if the key is ever exposed.
- Should I sign certificates directly with the root?
- For a small internal setup it is acceptable and much simpler. The reason public CAs do not is that the root key can then stay offline — an intermediate does the day-to-day signing, and a compromised intermediate can be revoked without reissuing every trust store.
- Where should the CA key live?
- Somewhere offline, encrypted, and backed up separately from anything internet-facing. Anyone with that key and its passphrase can issue certificates that every machine trusting your root will accept, for any hostname including ones you do not own.
References
- openssl-req(1) — creating the self-signed root
- CA/Browser Forum Baseline Requirements — what a publicly trusted CA is permitted to issue