[P 3] Revocation Is a Distribution Problem

The signing service can be offline for a week and nobody notices. Let the revocation list become unreachable and authentication fails across the estate for certificates that are perfectly valid. Why the distribution layer is the only part of a PKI that must be highly available, and how to build it so it is.


Your certificate authority can be switched off for a week and almost nobody will notice. Take away the ability to answer the question “has this certificate been revoked” and authentication fails across the estate within hours, for certificates that are entirely valid and have changed in no way at all.

This asymmetry is the most useful thing to understand about running a private PKI, and it is almost never how the subject is introduced. Issuance is an occasional, tolerant, retryable operation. Somebody needs a certificate, the request fails, they try again in an hour. Validation is continuous, synchronous and unforgiving. It happens every time a device authenticates to a network, every time a service presents a certificate, every time a domain controller is asked to vouch for a smart card, and it happens with a timeout measured in seconds. The infrastructure that serves validation data is therefore doing production work at production volumes, and the infrastructure that signs certificates is not.

Which means the interesting engineering in a PKI is not cryptographic. It is a small, ordinary web hosting problem, and treating it as an afterthought is how competent teams build hierarchies that fail in ways they cannot diagnose.


Two extensions, and the fact that they are frozen

Every certificate an authority issues carries two pieces of routing information. The authority information access extension says where to fetch the certificate of whoever signed this one, so a relying party can build the chain upward. The distribution point extension says where to fetch the revocation list covering this certificate, so a relying party can check the signer has not disowned it. Both are URLs. Both are written by the signing authority at the moment of signing.

And both are immutable from that moment. This is the property that makes the whole subject unforgiving. Changing the configuration on your authority changes what goes into certificates issued from then on, and does precisely nothing to the certificates already in the field. A certificate signed today with a five-year life will still be requesting that exact URL, from that exact hostname, in 2031. If your issuing authority signs a five-year certificate for the last time on the day before it expires, the URL in that certificate has to survive a decade.

The URL is not infrastructure that points at the certificate. It is part of the certificate.

I labour this because the people who make DNS and web hosting decisions in most organisations are not the people who built the PKI, and the request to retire a small internal web server that “only serves a couple of files” is entirely reasonable on its face. The answer has to be that the name is load-bearing for the lifetime of every certificate that carries it, and that is a conversation which goes far better before the server exists than after somebody has decommissioned it.


Why HTTP, and why not the directory

A Windows certificate authority publishes to the directory by default. That is a sensible default for the world it was designed in, where every relying party was a domain member sitting on the corporate network, and it is close to useless for the world most estates now operate in. A directory location resolves for a machine that is joined to the domain, can reach a domain controller, and is inside the network boundary. It resolves for nothing else. Not a phone. Not a Mac. Not a printer. Not a contractor’s laptop. Not a service running in a cloud subscription. Not a domain-joined machine on a hotel network, which is the population that generates most of your validation traffic and all of your support tickets.

So the HTTP location is the one that actually does the work, and the directory location, if you keep it, is a fast path for the subset of clients that can use it. Get the ordering right and the directory entry is a small optimisation. Get it wrong, or omit HTTP entirely, and you have built a PKI that works perfectly in the office.

The other half of this is the one that catches people who are being careful. The distribution point must be HTTP and not HTTPS, and the reason is a dependency loop rather than an oversight. To validate the certificate protecting an HTTPS connection, a client needs to check revocation. To check revocation it needs to fetch the list. To fetch the list over HTTPS it must first validate the certificate protecting that connection. Windows does not support HTTPS in these extensions, and a client that encounters one fails in a manner that is genuinely tedious to trace, because everything about the configuration looks correct and secure. Serving revocation data unencrypted feels wrong the first time you do it. It is fine: the list is signed by the authority, so tampering is detectable, and there is nothing confidential in a list of certificates you have already disowned.

There is a second reason, less elegant and just as convincing. A certificate in front of that endpoint is one more certificate with an expiry date, on a renewal schedule somebody has to own, protecting a service whose entire job is to be available when other certificates are being checked. Public certificate lifetimes are on a schedule that takes them from a year to under two months by 2029, so that renewal burden is growing rather than shrinking. Adding it to the one endpoint that must never be down, in exchange for nothing, is a poor trade.


The name is the decision

Before any of the availability engineering, there is a naming decision that is easy to get wrong in a way you cannot correct. The name in your distribution point must resolve, to an address you control, for every client that will ever validate one of your certificates, for as long as those certificates live.

The straightforward case is an Active Directory domain whose DNS zone you own outright. The PKI name is a record in that zone, your internal DNS servers answer for it, and the decision is over. The case that traps people is the common enterprise pattern where the directory runs as a child of a publicly registered domain, so the internal team owns the child zone while the parent is registered externally and managed by somebody else, possibly a registrar, possibly a corporate group with a change process measured in weeks.

Putting the PKI name in that parent zone looks tidier and is a mistake. You need a record that resolves to internal addresses for internal clients, in a zone you can change at short notice for the next ten years, and an externally managed public zone gives you neither. The correct move is to keep the PKI name inside the child zone your own DNS servers are authoritative for, even though the resulting name is longer and less elegant. Elegance is not a property anybody will notice. A change request to an external DNS team during an outage is a property everybody will notice.

Whatever you choose has to be used with absolute consistency afterwards, in both policy files, in every distribution point command on both authorities, and in the web server configuration. A hierarchy where the root advertises one name and the issuing authority advertises a variant of it is a hierarchy where half your validation failures are invisible until a specific population of clients hits the wrong one.


Two servers, one name, and no replication

Now the availability question, which is where most designs settle for something that looks redundant and is not.

The obvious approach is two web servers and two DNS records for the same name, letting clients alternate between them. This is redundancy in the sense that two machines exist. It is not availability, because DNS performs no health checking whatsoever. When one server fails, DNS keeps handing out its address to roughly half the clients that ask, and each of those clients waits out a retrieval timeout before it tries anything else. Certificate validation has a short patience, so a proportion of validations simply fail while both servers are still listed as perfectly healthy in DNS. It is a design that degrades into intermittent, client-specific, unreproducible authentication failures, which is the worst failure mode there is because it looks like something else.

A load balancer in front of the two servers, probing the actual path that serves the files rather than merely checking that a port is open, fixes that properly. One name, one address, health-checked, and a failed node removed from rotation in seconds. If you have load balancing infrastructure this is the answer and there is not much to debate. If you do not, DNS round robin is a defensible compromise provided you write down that it is one, and keep the record’s time to live short so that manually removing a failed address takes effect in minutes rather than hours.

That settles how clients reach the files. The more interesting question is how the files get onto two servers in the first place, and here the instinct almost everybody has is the wrong one. The instinct is to pick a replication technology: put the folder in a replicated share, or schedule a copy from one server to the other. Both work, and both introduce a component that can fail silently in a way nobody monitors. A replication topology that stops converging leaves one server serving a revocation list that expired last month, and because the load balancer sees a healthy web server returning a valid file with a 200 response, it will keep sending clients to it. You have built a system where half your clients get a stale answer and every health check is green.

The design I settle on removes the replication layer entirely. The issuing authority is configured with two publication paths, one pointing at each web server’s share, and on every publication cycle it writes the revocation list to both of them itself. There is no synchronisation, no convergence delay, and no third component to monitor. If a publication fails, it fails on the authority, which is a place you are already watching, rather than in a replication service nobody has looked at since the build.

The issuing CA writes its certificate revocation list over UNC directly to both PKI-WEB01 and PKI-WEB02 on every publication cycle, with no replication layer between them. The offline root publishes its list locally and somebody carries it to both servers by hand once a year. Both web servers sit behind the single name pki.catsnackjack.com, which is the only URL written into issued certificates, and every relying party fetches revocation data from that name over HTTP.

The two write paths never appear in a certificate. The one HTTP name is the only thing clients ever see.

The distinction in that pullquote is worth dwelling on, because conflating the two is the single most common configuration error in this area. An authority’s distribution point configuration is a list of entries, and each entry carries flags describing what the authority should do with it. Some entries are places the authority writes files. Some entries are URLs the authority stamps into the certificates it issues. They are not the same list serving two purposes; they are one list where each entry has a role. The two file paths in this design are write targets only and no client is ever told about them. The single HTTP name is stamped into certificates and is never written to directly. Getting this backwards produces certificates advertising a network share as their distribution point, which fails for every client that is not a domain member with access to that share, which is most of them.

The root is the exception, and it is a manual one. It publishes its revocation list to a local folder, because it has no network, and somebody carries that file to both web servers once a year. That is the annual appointment from the previous article, and it is the only part of this architecture that is not automatic.


What failure actually looks like

It is worth being precise about the outage this is all defending against, because it does not announce itself. Nothing expires. No certificate becomes invalid. What happens is that relying parties can no longer complete a check they are obliged to perform, and a check that cannot complete is treated as a failure rather than a pass. The result is authentication breaking in several unrelated systems at once, with no change having been made, no certificate having lapsed, and every certificate the team inspects looking entirely healthy.

Windows surfaces this as a revocation offline error, and the causes worth memorising are a small set: the distribution point is unreachable, the file was never published there, the published list has passed its expiry, or the client is holding a cached copy that has aged out. Each has a different fix and they are easy to tell apart once you know to look, which is the entire value of having read this before it happens rather than during.

There is a second audience for your revocation data now, and it constrains the design more tightly than your internal clients do. If you use certificate-based authentication against Entra ID, Microsoft’s service is a relying party, and it will not reach anything that is only published internally. It supports one distribution point per authority rather than a list, it requires the location to be plainly reachable, it enforces limits on how large the list may be and how long the download may take, and it does not support the online status protocol at all. Those constraints are worth designing to even if you are not using that feature today, because they push you toward exactly the architecture that serves everyone else well: one externally resolvable name, over plain HTTP, served fast, with a list you keep small.


The online responder, and when it is worth it

There is a second mechanism for answering the revocation question, in which a client asks about one specific certificate and receives a signed answer about that certificate alone, rather than downloading a list of everything the authority has ever disowned. It is a real option, Microsoft still ships it, and it recently gained post-quantum signing support, so it is not a legacy component.

It is worth deploying when the list has grown large enough that downloading it is a meaningful cost for clients, or where validation latency genuinely matters. It is not worth deploying in a small internal estate that revokes a handful of certificates a year, and it is emphatically not a replacement for the list, because the responder derives its answers from exactly the same revocation list your authority publishes. A stale list produces a responder that answers confidently and wrongly, which is worse than a failure. If you do deploy it, note that its availability story has the same shape as everything else in this article: multiple responders behind one name, health-checked, with the name and not a node written into your certificates.


None of this is complicated. It is two web servers, a share, a virtual directory, one DNS name and a handful of configuration entries, and it can be built in an afternoon. What makes it worth an article of its own is that it is the only part of the hierarchy where an ordinary infrastructure decision, made by someone with no visibility of the PKI, can take down authentication for an entire organisation. The build sheet that follows makes it concrete, and it closes the loop the previous article deliberately left open: the URLs the root recorded are about to become real, and its revocation list is about to be reachable from outside the network for the first time.


On-Prem PKI
‹ Previous: [P 2.1] Build Sheet: The Offline Root CA
Next: [P 3.1] Build Sheet: Redundant CRL and AIA Web Servers