When a certificate authority you run or trust is compromised, the first 24 hours are about three things: contain the key (stop it from signing anything new), find every certificate, trust store and pinned key that depends on it, and start replacing trust before you rely on revocation. The first week is about reissuing every affected certificate under a new key, removing the compromised CA from every trust store you control, and proving with evidence that nothing still chains to it. Revocation alone is not the fix, because a stolen CA key can sign its own "good" answers.
This post is the runbook. If you want the background on why CA compromise is so damaging, read our explainer on certificate authority compromise risks, and for what happens to your services when a browser stops trusting a public CA, see what happens if a browser distrusts your certificate authority. This post stays practical: who does what, in which order, with which commands. Certificate and revocation behaviour comes from RFC 5280 (the X.509 profile for the internet) and RFC 6960 (OCSP), revocation timelines for publicly trusted CAs come from the CA/Browser Forum Baseline Requirements, and the inventory and lifecycle practices follow NIST SP 1800-16, the NCCoE practice guide "Securing Web Transactions: TLS Server Certificate Management".
Key takeaways
- Treat a CA compromise as two incidents at once: a key compromise (stop the signing) and a trust incident (every relying party that trusts the CA is exposed until it stops trusting it).
- Revocation is necessary but not sufficient. A compromised CA key can sign CRLs and OCSP responses, so revocation of a compromised CA certificate has to come from its parent, and a compromised root can only be removed from trust stores.
- Inventory decides how fast you recover. Search by issuer and Authority Key Identifier, not only by hostname, and include client certificates, code signing, device certificates, service mesh identities, bundled trust stores and pinned keys inside applications.
- Never reuse the compromised key pair. Reissue under a new CA key, with a new key for every end entity certificate whose key the attacker could have touched.
- Applications that ship their own CA bundle or pin a key do not pick up operating system trust store changes. An SBOM of your software tells you which ones they are.
- Close the incident with evidence: scans that show no endpoint still presents a certificate chaining to the old CA, and trust stores that no longer contain it.
First, decide which incident you have
"CA compromise" covers several different situations, and the right first move depends on where the compromised key sits and who owns it. Before anyone revokes anything, the incident commander should answer four questions and write the answers in the incident channel.
- Which key? A root key, an intermediate (subordinate) CA key, an issuing CA key, a delegated OCSP responder key, or a registration authority credential that can request certificates without holding a key.
- Who operates it? Your own private CA, a managed private CA service you control, a public CA that issued your certificates, or a partner CA you trust for client authentication or federation.
- What did it sign? TLS server certificates, mutual TLS client certificates, code signing, S/MIME, device identity, workload identity in a service mesh, or other CAs.
- What do you know about the window? The earliest time the key could have been exposed, and the time you contained it. Everything signed inside that window is suspect, and anything misissued may not appear in your issuance database at all.
The decision table below maps the common combinations to the first action.
| Situation | Who acts | First action | Revocation path | Real fix |
|---|---|---|---|---|
| Your private issuing CA key exposed | You | Stop issuance, take the CA offline | Parent CA revokes the issuing CA certificate on its CRL with reason cACompromise | New issuing CA, reissue all leaves |
| Your private root key exposed | You | Stop issuance, freeze all intermediates | None that clients can rely on; a root is a trust anchor | Remove root from every trust store, build a new hierarchy |
| A public CA that issued your TLS certificates reports a compromise | The CA, then you | Order replacement certificates from another CA | The CA (or its parent) revokes affected certificates | Replace certificates before the CA is distrusted |
| A partner or federation CA you trust is compromised | The partner, then you | Remove or restrict the partner CA in your trust stores | Partner revokes; you cannot rely on it | Accept only certificates from the partner's new CA |
| Delegated OCSP responder key exposed | CA operator | Stop the responder, issue a new responder certificate | Depends on the ocsp-nocheck extension (see below) | New responder key, short validity |
| RA or issuance API credential stolen, CA key safe | CA operator | Revoke the credential, audit issuance logs | Revoke every certificate issued by the stolen credential | Fix authentication on issuance |
The rest of this runbook assumes the hardest common case: a CA key you either operate or depend on can no longer be trusted, and you need to move every dependent system to a new chain of trust.
Why revocation alone does not fix a CA compromise
It is tempting to treat this like a leaked server key: revoke the certificate and move on. That works for an end entity certificate because a trusted CA vouches for the revocation. It does not work cleanly for a CA, and understanding why shapes everything else in the runbook.
RFC 5280 defines two pieces of revocation data. A certificate revocation list (CRL) is a list of revoked serial numbers signed by the CA (or a delegated CRL issuer), and each entry can carry a reason code. The reason codes RFC 5280 defines include keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn and aACompromise. RFC 6960 defines the Online Certificate Status Protocol (OCSP), where a client asks a responder about one certificate and gets back good, revoked or unknown, in a response signed by the CA itself or by a responder the CA delegated.
Both mechanisms are signed by the issuing CA or someone it authorised. If the attacker holds the issuing CA key, the attacker can also produce a CRL that leaves out a certificate, or authorise an OCSP responder that says good. So:
- An intermediate or issuing CA must be revoked by its parent. The parent's CRL lists the compromised CA certificate with reason
cACompromise, and clients that build and check the full chain will reject anything under it. That only helps clients that actually check revocation for intermediate certificates. - A root has no parent. RFC 5280 path validation treats the trust anchor as an input to the algorithm, and how a relying party chooses or removes its trust anchors is outside the certificate profile. In practice that means the only reliable response to a compromised root is to remove it from every trust store that contains it.
- Delegated OCSP responders deserve their own check. RFC 6960 lets a CA mark a responder certificate with the
id-pkix-ocsp-nocheckextension, which tells clients not to check that responder certificate's own revocation status. RFC 6960 warns that CAs issuing such a certificate "should realize that a compromise of the responder's key is as serious as the compromise of a CA key used to sign CRLs, at least for the validity period of this certificate", and advises a very short lifetime with frequent renewal. If an attacker obtained a responder certificate withocsp-nocheck, it stays usable until it expires.
There is a second, practical reason. Many clients treat revocation checking as soft fail: if they cannot reach the OCSP responder or download the CRL, they accept the certificate. An attacker who can intercept traffic can often also block the revocation check. Revocation is a signal you must send, and it will help some clients, but the plan cannot depend on it. The plan depends on replacing certificates and removing trust.
The first hour: contain and convene
The first hour is short on technical work and long on coordination. The goals are to stop new damage, preserve evidence, and get the right people deciding together.
| Step | Owner | What to do | Done when |
|---|---|---|---|
| 1 | Incident commander | Open the incident, name the commander, the PKI lead, the communications lead and a scribe | Roles posted in the incident channel |
| 2 | PKI lead | Stop issuance from the affected CA: disable the issuance API, ACME endpoints and RA accounts | No new certificates can be issued |
| 3 | PKI lead | If you operate the key in an HSM or cloud KMS, disable or restrict the key (do not destroy it yet) | Key cannot sign; audit trail intact |
| 4 | Security operations | Preserve evidence: HSM and KMS audit logs, CA database snapshot, issuance logs, access logs for operators | Copies stored outside the affected environment |
| 5 | Incident commander | Record the compromise window: earliest possible exposure and time of containment | Window written in the incident record |
| 6 | Communications lead | Identify who must be told: internal service owners, partners who trust this CA, and, for a publicly trusted CA, the root store programs and auditors | Notification list drafted |
Two traps catch teams in this hour. The first is destroying the key immediately. If the key is in an HSM you control, disabling it stops misuse, and destroying it removes your ability to sign a final CRL with the old key if your plan needs one. Decide deliberately, then destroy. The second trap is assuming the issuance database is complete. A stolen key can sign certificates that never touched your CA software. Plan as if there are certificates you will never see in your own records.
Commands: freeze issuance and capture state
The exact commands depend on your CA software. The pattern is the same everywhere: stop the service, keep the data.
# Snapshot the CA database and configuration before anything else changes
sudo systemctl stop my-ca-service
sudo tar --xattrs -czf /secure/evidence/ca-state-$(date -u +%Y%m%dT%H%MZ).tgz /var/lib/my-ca /etc/my-ca
sha256sum /secure/evidence/ca-state-*.tgz > /secure/evidence/ca-state.sha256
# Record the CA certificate you are responding to
openssl x509 -in issuing-ca.pem -noout -subject -issuer -serial \
-fingerprint -sha256 -ext subjectKeyIdentifier,authorityKeyIdentifier
Write down the CA certificate's subject, serial number, SHA-256 fingerprint and Subject Key Identifier. The Subject Key Identifier is the value you will search for in the next phase, because every certificate the CA issued carries it as its Authority Key Identifier (RFC 5280 defines both extensions in section 4.2.1).
Hours 1 to 24: inventory everything that trusts or depends on the CA
Inventory is where CA compromise responses succeed or fail. NIST SP 1800-16 describes a formal TLS certificate management program, demonstrated with automation, to prevent, detect and recover from certificate-related incidents; inventory and ownership are the base of that program. During a compromise you need that inventory in hours, not weeks.
There are two inventories to build, and they are different.
- Certificates issued by the compromised CA. These need to be replaced.
- Places that trust the compromised CA. These need to stop trusting it.
A third list matters for public CAs and for partners: places that pin the CA, an intermediate or a leaf key. These may break when you replace certificates, and they need their own change.
Inventory 1: certificates issued by the CA
Start with what your systems know, then go find what they do not.
Issuance records. Export every certificate the CA issued, from the start of the compromise window if you can bound it, or from the CA's creation if you cannot. Include certificates that were later revoked or expired, because you want to know which ones an attacker might have re-used.
Network scans. Scan the endpoints you own and pull the chain each one presents. Match on the issuer's key identifier, not only the issuer name, because a new CA may share a name with the old one.
# For each host:port, print the leaf, its issuer and the Authority Key Identifier
while read target; do
echo | openssl s_client -connect "$target" -servername "${target%%:*}" -showcerts 2>/dev/null \
| openssl x509 -noout -subject -issuer -serial -enddate \
-ext authorityKeyIdentifier 2>/dev/null \
| sed "s|^|$target |"
done < endpoints.txt > scan-$(date -u +%Y%m%d).txt
# Flag every leaf whose Authority Key Identifier matches the compromised CA's Subject Key Identifier
grep -i -B6 "AB:CD:EF:01:23" scan-*.txt
Replace AB:CD:EF:01:23 with the real key identifier you recorded. Run the scan from inside each network zone, because internal services and mutual TLS endpoints are rarely visible from outside.
Certificate files on disk and in secret stores. Certificates live in Kubernetes Secrets, cloud certificate managers, load balancers, CDN configurations, configuration management repositories, Java keystores and application bundles. Search them all by issuer key identifier.
# PEM files on a host
sudo find / -xdev \( -name '*.pem' -o -name '*.crt' -o -name '*.cer' \) 2>/dev/null \
| while read f; do
openssl x509 -in "$f" -noout -ext authorityKeyIdentifier 2>/dev/null \
| grep -qi "AB:CD:EF:01:23" && echo "$f"
done
# Java keystores
keytool -list -v -keystore app.jks -storepass:env KS_PASS | grep -i -A2 "AuthorityKeyIdentifier"
# Kubernetes TLS secrets (read-only)
kubectl get secrets -A --field-selector type=kubernetes.io/tls -o json \
| jq -r '.items[] | "\(.metadata.namespace)/\(.metadata.name) \(.data["tls.crt"])"' \
| while read name crt; do
echo "$crt" | base64 -d | openssl x509 -noout -ext authorityKeyIdentifier 2>/dev/null \
| grep -qi "AB:CD:EF:01:23" && echo "$name"
done
Public certificates. If the CA is publicly trusted, query Certificate Transparency logs for certificates issued for your domains. Certificate Transparency records publicly trusted TLS certificates, so it can reveal certificates for your names that your own records do not show. Private CAs do not log there, so for a private CA your issuance database and your scans are all you have.
Non-TLS certificates. A CA that issues more than server certificates has more to find. Look for mutual TLS client certificates in devices and services, code signing certificates used in build pipelines, S/MIME certificates, VPN and Wi-Fi (802.1X) certificates, and workload identities in a service mesh. Each has an owner who will need a new certificate.
Inventory 2: places that trust the CA
Every client that has the compromised CA in a trust store is exposed until you remove it. Trust stores are scattered.
| Trust store | Where it lives | How to check |
|---|---|---|
| Debian and Ubuntu system store | /usr/local/share/ca-certificates/ and /etc/ssl/certs/ | ls /usr/local/share/ca-certificates/, then update-ca-certificates after changes |
| RHEL, Fedora and derivatives | /etc/pki/ca-trust/source/anchors/ | trust list, then update-ca-trust after changes |
| Java runtimes | $JAVA_HOME/lib/security/cacerts and app-specific truststores | keytool -list -cacerts |
| Windows | Local machine Trusted Root and Intermediate stores, often set by Group Policy | certutil -store Root, certutil -store CA |
| macOS | System and login keychains, often set by device management profiles | security find-certificate -a -Z /Library/Keychains/System.keychain |
| Container images | Base image CA package plus any certificates copied in at build time | Inspect the image filesystem and its SBOM |
| Language runtimes | Bundled CA files inside language packages (Python's certifi, for example) and runtime-specific stores | SBOM of the application, then the package's CA file |
| Service mesh and proxies | Mesh root of trust, sidecar and gateway configuration | Mesh CA configuration and proxy trust bundles |
| Network devices and appliances | Load balancers, firewalls doing TLS inspection, VPN concentrators | Device configuration export |
The rows that surprise teams are container images and language runtimes. A container built six months ago still carries the CA file from the day it was built. A Python service that uses a bundled CA file trusts whatever that file contains, not what the host operating system trusts. Updating the host store does nothing for either. For a private root that was added to images at build time, you have to find every image that copied it in and rebuild.
Inventory 3: pinned keys and certificates
Certificate pinning means an application accepts only a specific certificate, public key or CA, regardless of what the trust store says. Pins live in mobile apps, desktop clients, IoT firmware, internal SDKs and service-to-service clients. When you replace a pinned certificate or move to a new CA, every pinned client breaks unless it already carries a backup pin for the new key.
Find pins in three ways: search code for pinning APIs and hard-coded hashes, check your SBOMs for libraries that implement pinning, and ask the owners of every mobile and embedded client directly. For mobile apps the fix depends on users installing an update, so this list drives your reissue timeline.
Prioritise the inventory
You will not replace everything at once. Rank by exposure and by blast radius.
| Priority | What | Why |
|---|---|---|
| P0 | Internet-facing TLS endpoints and authentication services (identity provider, SSO, API gateways) | Easiest to impersonate, highest value to an attacker |
| P0 | Code signing certificates issued in the window | A signed malicious build is trusted by every installer |
| P1 | Mutual TLS between services and to partners | Lets an attacker impersonate a service or a client |
| P1 | Trust stores on clients that talk to the outside world | Every one of them can be fooled by a misissued certificate |
| P2 | Internal-only TLS endpoints | Lower exposure, but still impersonation risk inside the network |
| P2 | Device and Wi-Fi certificates | Large numbers, slower rollout, plan in waves |
Hours 4 to 24: revoke and signal, with eyes open
With containment done and the inventory running, send the revocation signals. They will not protect every client, but they protect the ones that check, and they create the record that auditors, partners and root programs expect.
If you operate the CA
Compromised issuing or intermediate CA. Use the parent CA (usually an offline root) to revoke the compromised CA certificate. Publish a new CRL from the parent with the reason code cACompromise, and make sure the CRL Distribution Point in your certificates points at a location that serves it.
# Example with an OpenSSL-based offline root (adapt to your CA software)
openssl ca -config root-ca.cnf -revoke issuing-ca.pem -crl_reason CACompromise
openssl ca -config root-ca.cnf -gencrl -out root-ca.crl
openssl crl -in root-ca.crl -noout -text | grep -A3 "Serial Number"
Bring the root online only under your normal key ceremony controls, with witnesses and a log.
Leaf certificates under the compromised CA. A CRL signed with a compromised key carries limited assurance, but it still helps clients that check leaf revocation and not intermediates, so many teams publish a final CRL revoking all leaves before retiring the CA. Either way, the leaves are replaced in the next phase.
OCSP. Point the OCSP responder for the old CA at revoked status for the CA certificate (from the parent's responder) and, where possible, for its leaves. Retire any delegated responder certificate that the old CA issued, and if those carried ocsp-nocheck, note their expiry dates in the incident record: those are the dates after which the attacker can no longer use them.
# Check what an OCSP responder says about a certificate
openssl ocsp -issuer root-ca.pem -cert issuing-ca.pem \
-url http://ocsp.example.internal -resp_text -noverify | grep -E "Cert Status|Revocation Reason"
The -noverify flag skips verification of the responder's signature, so use this only to read the status, not as proof. Drop the flag and add -CAfile once you trust the responder certificate.
If a public CA you depend on is compromised
You do not revoke anything yourself, except your own certificates if your keys may be affected. Your job is to stay ahead of the CA's revocations and any distrust decision.
The CA/Browser Forum Baseline Requirements set revocation deadlines for publicly trusted CAs. For subscriber certificates, section 4.9.1.1 requires revocation within 24 hours for a set of reasons that include evidence of a key compromise (for certificates other than short-lived ones, which the BRs treat separately), and within five days for a second set, where a CA should still aim for 24 hours. The wording here follows version 2.3.1 of the Baseline Requirements, so check the current text before you quote the deadlines. For subordinate CA certificates, section 4.9.1.2 gives the issuing CA seven days to revoke for reasons that include compromise of the subordinate CA's private key. Read those clauses as a warning about your timeline: if your certificate is in scope, it can be revoked in a day, and if your issuing intermediate is in scope, the whole chain can be gone in a week. Order replacement certificates from a second CA on day one, not when the revocation email arrives.
If a partner CA you trust is compromised
Restrict trust on your side immediately: for mutual TLS and federation, accept only certificates from the partner's replacement CA. Ask the partner for the compromise window, the certificates issued in it and the new CA certificate, delivered through a channel that does not depend on the compromised PKI.
Hours 12 to 24: remove trust where you control it
For a compromised root, and for any CA you have decided not to trust again, removal from trust stores is the real fix. Do it in waves, starting with the systems that talk to the outside world.
Warning: destructive commands. The next block removes trust anchors. Run it only on systems whose replacement certificates are already deployed, and archive each removed certificate first.
# WARNING: the commands in this block are destructive. They remove trust anchors,
# and every connection that depends on certificates under them will start to fail.
# Run them only after the reissue wave for that system is live, and keep a copy of
# each removed certificate in your evidence archive.
# Debian / Ubuntu: remove a locally added CA and rebuild the store
sudo rm /usr/local/share/ca-certificates/old-internal-root.crt
sudo update-ca-certificates --fresh
# RHEL / Fedora: move the anchor out and rebuild
sudo mv /etc/pki/ca-trust/source/anchors/old-internal-root.pem /root/removed-anchors/
sudo update-ca-trust extract
# Java: delete from a truststore
keytool -delete -alias old-internal-root -keystore truststore.jks -storepass:env TS_PASS
# Windows (elevated): remove from the machine Root store by thumbprint
certutil -delstore Root <SHA1-thumbprint>
# macOS: remove from the System keychain by SHA-1 hash
sudo security delete-certificate -Z <SHA1-hash> /Library/Keychains/System.keychain
For Windows and macOS fleets, make the change in Group Policy or the device management profile that installed the CA in the first place, or it comes back at the next policy refresh. For container images, rebuild from a base image that does not include the old CA and remove any build step that copies it in. For language-bundled CA files, update the package or the file the application points to and redeploy.
Removing a root that still has valid certificates under it will break connections that rely on those certificates. That is the point, but it means trust removal and reissuance must be sequenced together: reissue first for the systems that must stay up, then remove trust, then watch for failures.
Days 2 to 7: reissue under a new chain of trust
Reissuance is the long part. The rule is simple: new CA key, new leaf keys, no reuse.
Build the new CA correctly
If you operate the CA, stand up a new issuing CA under an uncompromised root, or a new hierarchy if the root is gone. Generate the key non-exportable in an HSM or cloud KMS under a recorded ceremony, and give the CA a distinct subject name so operators can tell old from new in logs. Fix the cause first: if the old key was stolen from a host, or an RA credential was abused, the new CA does not accept requests until that path is closed.
Reissue in priority order
| Wave | Days | Scope | Notes |
|---|---|---|---|
| 1 | 2 | P0 internet-facing endpoints, identity provider, code signing | New key pair for each; deploy with the new chain |
| 2 | 2 to 3 | P1 mutual TLS between services and partners | Coordinate with partners so both sides switch together |
| 3 | 3 to 5 | P2 internal endpoints, service mesh identities | Mesh roots usually rotate through the mesh's own process |
| 4 | 4 to 7 | Devices, Wi-Fi and VPN certificates | Use your enrolment protocol; plan for offline devices |
| 5 | 5 to 7 | Pinned clients | Ship app updates with new pins before switching servers |
Generate new keys, not just new certificates. The investigation may later show broader access than the CA key, and a clean break costs little once you are reissuing anyway.
# New key and CSR for a server (ECDSA P-256 shown)
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
-keyout api.example.com.key -out api.example.com.csr \
-subj "/CN=api.example.com" -addext "subjectAltName=DNS:api.example.com"
# Verify the new leaf chains to the NEW CA, not the old one
openssl verify -CAfile new-root.pem -untrusted new-issuing-ca.pem api.example.com.crt
Where you already use automated issuance with ACME or a certificate manager in Kubernetes, reissuance is a configuration change: point the issuer at the new CA and trigger renewal. That is the strongest argument for automation, and it is why NIST SP 1800-16 demonstrates certificate management with an automated proof of concept.
Code signing needs a separate decision
Signatures outlive certificates. For each code signing certificate under the compromised CA, list the builds signed inside the compromise window, prove which of them came from your pipeline (build logs, provenance records, artifact hashes), and re-sign and re-release those you cannot prove. Signed build provenance and SBOMs are what make that separation possible.
Pinned clients
For each pinned client, ship an update that pins the new key (and a backup key) before you switch the server. For mobile apps, that means a release cycle and a period where both old and new pins are accepted. If a client pins the old CA key itself, it cannot accept anything under the new CA until updated. This is the case for preferring backup pins on keys you control, and for pinning at the level you are prepared to rotate.
Day 7: verify and close with evidence
An incident is closed when the evidence says so, not when the last ticket moves. Run four checks.
- No endpoint presents a chain to the old CA. Re-run the network scans from every zone and show zero matches on the old Authority Key Identifier.
- No trust store contains the old CA. Query system stores, Java stores, container images and bundled CA files. Rebuilt images should have new digests.
- Revocation is published. The parent CRL lists the old CA certificate with
cACompromise, and the OCSP responder returnsrevokedfor it. - Monitoring is in place. Alert on any certificate seen on your network, or in Certificate Transparency for your domains, that chains to the old CA.
Then write the post-incident review: timeline, root cause, compromise window, what was misissued, how long each wave took, which inventory sources were incomplete and what changes now. Most of the action items will be about inventory and automation.
The complete runbook at a glance
| Time | Phase | Key actions | Evidence produced |
|---|---|---|---|
| 0 to 1 hour | Contain | Stop issuance, disable key, preserve logs, define compromise window | Incident record, evidence archive with hashes |
| 1 to 12 hours | Inventory | Issued certificates, trust stores, pinned clients, prioritised | Inventory export, scan results |
| 4 to 24 hours | Revoke and signal | Parent CRL with cACompromise, OCSP updates, notifications | Published CRL, OCSP responses, notification log |
| 12 to 24 hours | Remove trust | Trust store removal in waves starting with external-facing clients | Change records per store |
| Days 2 to 5 | Reissue | New CA key, new leaf keys, waves by priority | Issuance log under the new CA |
| Days 4 to 7 | Pinned and devices | App updates with new pins, device re-enrolment | Release records, enrolment logs |
| Day 7 | Verify and close | Rescan, trust store audit, monitoring, review | Zero-match scans, review document |
Preparing before it happens
Every step above is faster if you prepared for it. Five controls change the outcome most.
A living certificate inventory and an SBOM per application. NIST SP 1800-16 frames TLS certificate management as a formal program whose job is to prevent, detect and recover from certificate-related incidents, and that starts with knowing every certificate, its owner and its issuer. The trust store and pinning questions are software questions too, so keep a current SBOM for every repository and image: then "which services bundle their own CA file" is a query, not an email thread.
Short lifetimes and automated renewal. If certificates already renew automatically, reissuing them under a new CA is a configuration change and a forced renewal.
Offline roots, separated issuing CAs and keys in hardware. Keep the root offline, use separate issuing CAs for TLS servers, clients, code signing and devices, and keep CA keys non-exportable in an HSM or cloud KMS with audited use. A compromise then hits one purpose, and the audit trail defines the window.
Backup pins and a second CA relationship. Pin at a level you can rotate, always ship a backup pin, and keep validated domains with a second public CA so replacement on day one is an order, not a procurement process.
A rehearsed runbook. Tabletop this runbook once a year with the PKI team, security operations, platform owners and communications.
Common mistakes
- Treating revocation as the fix. Revocation signals compromise to clients that check. It does not stop clients that soft fail, and it cannot be relied on when the CA key itself is the thing that was stolen. Replace certificates and remove trust.
- Searching only by hostname. Hostname searches miss client certificates, code signing, device certificates and anything issued for names you did not know about. Search by issuer key identifier.
- Forgetting bundled trust stores. Updating the host operating system store does nothing for container images built earlier or for applications that use their own CA file.
- Reusing keys. Reissuing a certificate on the old key pair, or rebuilding the CA with the old key, leaves the original exposure in place.
- Breaking pinned clients. Switching a server before pinned clients have the new pin turns a security incident into an availability incident.
- Closing on tickets instead of evidence. Close when scans and trust store audits show zero dependence on the old CA.
- Fixing the CA and ignoring the cause. If the key was stolen from a host or through an issuance credential, the new CA needs a different design.
Fix the dependency side, not just the certificates
A CA compromise is a PKI incident, but a large part of the recovery happens in software: rebuilding images without the old root, updating bundled CA packages, changing pinning code and shipping client releases. That work depends on knowing which components are in which application, and on getting fixes into dependencies quickly, including when an upstream maintainer has not released one.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Griffin, Safeguard's security model, opens a policy gated pull request that moves the affected dependency to the safe version, and your own CI runs your tests on it before anyone merges. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Auto-merge is a separate switch and stays off by default, so your team decides what merges on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Safeguard Gold rebuilds patched versions of open-source packages and images from source, signs each build, attaches an SBOM, SLSA provenance and VEX, and serves them from registry.safeguard.sh to your organization. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
Safeguard does not run your CA, revoke certificates or manage trust stores. Where it helps is the software side of this runbook. Safeguard generates SBOMs for your repositories and container images, so you can find the TLS libraries, bundled CA packages and certificate pinning dependencies in each application and image when you need to know which ones will not pick up a trust store change. Safeguard also produces signed attestations for the artifacts your pipelines build (SLSA provenance, SBOM and scan snapshots in in-toto format), signed with Safeguard's own key held in a cloud key management service and verified with cosign against Safeguard's published public key. Those signatures are not written to a public transparency log, and they do not depend on the PKI you are recovering, which helps when you need to show which builds came from your pipeline.
The demo below is a real Safeguard CLI session. It shows the CLI being installed, the assistant asked to fix a dependency finding, and a scan run to confirm the result. In a CA compromise, the same flow applies when you need to update a bundled CA package or a pinning library across a repository.
Click through it at your own pace, or open it full screen.
This demo sets up the Safeguard local runner on your own machine, approves it with a device code and then scans from the terminal. For a PKI owner it is a quick way to scan a repository and see which TLS and certificate handling components it depends on.
Click through it at your own pace, or open it full screen.
The last demo connects Claude to the Safeguard MCP server with OAuth and chooses which tools Claude can use. Once connected, a security operations lead can ask which projects include a given TLS library or CA bundle package from the assistant they already use.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard and follow the SBOM generation guide.
FAQ
What should you do first when a certificate authority is compromised?
Stop the CA from issuing, disable the key without destroying it, preserve the logs and define the compromise window. Then start the inventory of every certificate the CA issued and every trust store that contains it. Revocation and reissuance follow from that inventory.
Can you revoke a compromised root CA certificate?
Not in a way clients can rely on. A root is a trust anchor: in RFC 5280 path validation it is an input, not a certificate checked against a CRL. The response to a compromised root is removal from every trust store and a new hierarchy.
How do you revoke a compromised intermediate CA?
Revoke its certificate from the parent CA and publish the parent's CRL with the reason code cACompromise, and update the parent's OCSP responder. Clients that check revocation for intermediates will then reject the chain. Replace every leaf under it as well.
Is OCSP enough to protect clients after a CA compromise?
No. Many clients soft fail when they cannot reach the responder, and a compromised CA key can authorise its own responder. OCSP is one signal among several; replacing certificates and removing trust are what protect clients.
How fast must a public CA revoke certificates after a key compromise?
The CA/Browser Forum Baseline Requirements require revocation of subscriber certificates within 24 hours for reasons that include evidence of a key compromise, and give an issuing CA seven days to revoke a subordinate CA certificate whose private key was compromised. Plan your own replacement to beat those deadlines.
Do I need new private keys or just new certificates?
New keys. Reissue the CA under a new key, and generate a new key pair for each end entity certificate you replace. Reusing keys keeps any exposure the investigation has still to uncover.
What happens to certificate pinning when a CA is replaced?
Clients that pin the old CA key or old leaf keys will reject the new certificates. Ship client updates that include the new pin and a backup pin before you switch servers, and allow both during the transition.
How does an SBOM help with a CA compromise?
An SBOM lists the components inside each application and image, including TLS libraries, bundled CA packages and pinning libraries. It tells you which software will not pick up an operating system trust store change and needs its own rebuild or update.
Quick check
Your offline root is safe, but an issuing CA key was stolen. Is publishing a new CRL from the issuing CA enough?
No. A CRL signed with the stolen key carries limited assurance. Revoke the issuing CA certificate from the root with reason cACompromise, publish the root's CRL, and replace every leaf under a new issuing CA.
You removed an internal root from every server's operating system trust store. A Python service still connects to a host using a certificate from that root. Why?
The service most likely uses a bundled CA file rather than the system store, or runs in a container image built before the change. Check its SBOM and the CA file it actually loads, then update and redeploy.
A delegated OCSP responder certificate issued by the compromised CA carries the ocsp-nocheck extension. When does it stop being usable?
When it expires. Clients do not check revocation for a responder certificate with ocsp-nocheck, which is why RFC 6960 advises short lifetimes for those certificates.
Sources
- IETF RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile
- IETF RFC 6960: X.509 Internet Public Key Infrastructure Online Certificate Status Protocol (OCSP)
- CA/Browser Forum: Baseline Requirements for TLS Server Certificates
- NIST SP 1800-16: Securing Web Transactions: TLS Server Certificate Management
- Safeguard docs: Attestation signing
- Safeguard docs: Generate an SBOM