Skip to main content
RunBook Academy

Secrets, PKI & CertificatesIX · Certificate Lifecycle and RevocationLifecycle

Rotating a private key versus renewing a certificate

Advanced⏱ ~22 minopenssl

What you'll learn

  • Distinguish certificate renewal from key rotation by what each replaces
  • Explain why reissuing over a suspect key extends rather than ends an exposure
  • List the conditions that make key rotation mandatory rather than discretionary
  • Verify from the socket that the served public key actually changed

Prerequisites

Practice

Verified against OpenSSL 3.5.x teaching target; 3.0+ minimum · OpenSSH 10.x teaching target; 8.2+ minimum for certificate workflows · OpenBao 2.6.x · Smallstep step-ca 0.30.x · Certbot / Pebble Certbot current release; Pebble 2.10.x ACME test server · Kubernetes (cross-course target) 1.36.x · PostgreSQL 17.x · 2026-08-26

Not yet marked complete on this device.

Ask an on-call engineer to rotate a certificate and you will get one of two entirely different outcomes, because the phrase covers two operations that share a workflow and nothing else. One replaces a signed statement that was going to expire. The other replaces the secret that statement is about. Only one of them ends an exposure, and choosing the wrong one during an incident leaves the attacker in possession of a working credential with a later expiry date than the one they had before.

Two different operations that share a workflow

A certificate binds a name to a public key for a period. That gives two independent things to replace.

  • Renewal replaces the certificate. The same public key, or a new one, is certified again by the same issuing authority with a new serial and a later validity window. The reason to do it is that the current certificate is running out of time.
  • Rotation replaces the key pair. A new private key is generated, a new certification request is produced from it, and a new certificate is issued over the new public key. The reason to do it is that the current private key can no longer be assumed secret, or no longer meets the algorithm and strength you require.

Rotation always forces a renewal, because a certificate is bound to one specific public key and cannot be re-pointed at another. Renewal does not force rotation, and by default many automated clients reuse the existing key across renewals precisely because reuse keeps public-key pinning and hardware-backed key storage working.

That default is fine for routine, scheduled renewal. It is catastrophic as an incident response.

Why reusing the key after a compromise defeats the purpose

Consider what an attacker who has copied the private key actually holds. They hold the ability to complete a TLS handshake as your service, because the handshake proves possession of the key that matches the public key in the presented certificate. They do not need your server, your configuration or your network. They need the key and a copy of the certificate, and the certificate is public.

Now issue a replacement certificate over the same key pair. The new certificate names the same public key. The attacker’s copy of the private key matches it exactly as well as it matched the old one. The only thing that changed is the expiry date, which has moved further into the future.

The direction of the dependency is worth stating plainly. Revocation acts on a certificate. Compromise acts on a key. A single key can sit behind several certificates, including ones you have forgotten, so responding to key compromise by revoking one certificate leaves the others usable. The only action that decisively ends the value of a stolen private key is generating a different one and retiring everything issued over the old one.

When rotation stops being optional

flowchart TD
    A["Certificate change needed"] --> B{"Has the private key\nbeen exposed or\nis it suspect?"}
    B -- "yes" --> C["Rotate the key\nthen reissue"]
    B -- "no" --> D{"Algorithm, curve or\nstrength changing?"}
    D -- "yes" --> C
    D -- "no" --> E{"Key moving to or from\nhardware protection?"}
    E -- "yes" --> C
    E -- "no" --> F["Renew over the\nexisting key"]

The decision tree is short because the qualifying conditions are specific. Rotate the key when any of the following is true, and renew over the existing key otherwise.

  • The key file has left the host. A backup restored to a laptop, a copy attached to a ticket, a paste into a chat thread, a key baked into a container image pushed to a shared registry: each is an exposure whether or not anyone can name a misuse.
  • Someone who should no longer have access did have access. A departing administrator with read access to the key directory, a contractor with a restored snapshot, or a build agent whose credentials were later found in a public repository.
  • The host was compromised. Any successful intrusion on a machine holding the key is a key compromise, because reading a file is the cheapest thing an intruder does.
  • You are changing the algorithm or its parameters. Moving from RSA to an elliptic-curve key, or changing curve or modulus size, requires a new key pair by definition.
  • The key is moving into or out of hardware. A key generated inside a hardware module cannot be exported, so adopting hardware protection means generating a new one there.

Notice what is absent from that list. Routine expiry does not require rotation. Neither does a change of subject alternative names, a change of issuing authority, or an ordinary configuration improvement. Rotating on every renewal out of habit is not free: it breaks any consumer that pinned the public key, and it multiplies the number of key transitions your estate has to survive.

Executing the swap so both halves land together

A rotation replaces two files that must agree. If a process reads the new certificate with the old key, or the old certificate with the new key, the public key in the certificate does not correspond to the private key and the service refuses to serve. Stage everything, verify correspondence, then move both into place before reloading.

umask 077
STAGE=/root/rotation-staging
install -d -m 0700 "$STAGE"

# 1. A genuinely new key pair, generated on the host that will use it.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 \
    -out "$STAGE/app.key.new"

# 2. A fresh request, signed by the new private key to prove possession.
openssl req -new -key "$STAGE/app.key.new" -sha256 \
    -subj "/CN=app.lab.example" \
    -addext "subjectAltName=DNS:app.lab.example,DNS:www.app.lab.example" \
    -out "$STAGE/app.csr"

Once the issuing authority returns the certificate, prove that the served public key really changed. Comparing serials only tells you a new certificate is in place, which is also true after a plain renewal. The digest of the public key is what distinguishes rotation from renewal on the wire.

HOST=app.lab.example
PORT=443

# Record this before the change, and compare after the reload.
openssl s_client -connect "$HOST:$PORT" -servername "$HOST" </dev/null 2>/dev/null \
    | openssl x509 -noout -pubkey \
    | openssl sha256

A different digest proves the key rotated. An identical digest after what was supposed to be a rotation means the tooling reused the existing key, which is the silent failure this whole lesson exists to prevent. The same digest computed directly from the private key file must match the one observed on the socket; if it does not, the process is serving a certificate that belongs to a different key.

What breaks when the public key changes

Rotation is more disruptive than renewal because some consumers are bound to the key rather than to the name. Knowing which ones exist in your estate is the difference between a planned rotation and an unplanned second incident.

Public-key pinning is the obvious case. A client configured to accept only a specific public key, whether through a pinned digest in application configuration, a mobile application pin or a monitoring assertion, rejects the rotated certificate even though it is perfectly valid and correctly issued. The remedy is to distribute the new pin before the rotation and to keep both pins accepted across the transition, which is only possible if the pin set is deployable independently of the certificate.

Mutual TLS deployments have the same problem in the other direction: rotating a client key means every server that authorises that client must accept the new one. Where authorisation is by certificate fingerprint rather than by issuer and subject, the rotation is a coordinated change across two teams.

Finally, anything that cached the certificate rather than fetching it keeps presenting the old public key. Container images with baked-in material, appliance configurations imported months ago and forgotten copies inside keystores all fall into this category, which is why the socket-level check has to be repeated at every place TLS terminates.

Production discipline

  1. Record the trigger in the change, not just the action. A change titled certificate rotation should state whether the key changed and why, because the two operations have different verification requirements.
  2. Treat any key exposure as a key compromise. Arguing about whether the copy was ever read costs more than generating a new key pair.
  3. Inventory every certificate issued over a key, not every certificate for a name. Compromise follows the key, and one key can appear in several certificates and several environments.
  4. Verify the public key digest, not only the serial. A serial change is satisfied by a renewal that reused the key, which is exactly the outcome an incident response must not accept.
  5. Know your pinners before you rotate. Distribute the new pin ahead of the change and accept both across the transition, or accept that rotation is an outage for those clients.

Cross-course references

  • Linux for Production Sysadmins - Part LXXII (Secrets) covers private key handling on the host, including passphrases, agents and the copies that make a key unrotatable in practice.
  • Git, CI/CD & GitOps for Infrastructure Engineers - Part XCIV (IncSecretLeak) covers responding to credential material that has reached a repository, which is the most common trigger for the rotation this lesson describes.
  • Kubernetes for Production Sysadmins - Part LXV (SecretsSec) covers where key material is stored for workloads and who can read it, which determines how wide an exposure actually is.

Quiz

Knowledge check · 4 questions

  1. Q1. A server private key was found in a container image on a shared registry. The team reissues the certificate from the same authority, reusing the existing key, and reloads. What has been achieved?

  2. Q2. Every certificate renewal requires a new key pair to be generated.

  3. Q3. Which observation distinguishes a completed key rotation from an ordinary renewal, when both produce a new serial number?

  4. Q4. Decide what must change and in what order.

    A departing administrator held read access to /etc/ssl/private on six web nodes and on the configuration management server that distributes the material. The same key pair has been used for app.lab.example since 2024 and is also embedded in an internal appliance configuration that a different team maintains. The certificate itself does not expire for another 70 days.

Passing score: 75%. Answers are checked in this browser.