The certificate an agent provisioned and nobody agreed to renew
An AI agent that ran certbot once did the work correctly and made no commitment about the renewal. The setup is in your repository; the recurring obligation it created is in nobody's calendar.
Ninety days ago, an agent set up TLS on a new subdomain. It picked a challenge type, ran certbot, wrote the nginx block, reloaded, and verified the padlock. It was correct, it was fast, and it was finished in about four minutes.
Today the certificate expires.
Nothing went wrong in that session. The work was good. The problem is structural: the agent completed a task that quietly created a recurring obligation, and only the task had an owner.
Setup is a transaction, maintenance is a relationship
A human engineer doing that work carries something the agent does not. They leave the terminal knowing that a thing now exists which will need attention later. That knowledge is fuzzy and unreliable — it is the reason certificates lapsed long before agents existed — but it is not zero. It occasionally becomes a diary entry, a runbook line, or a nagging feeling in week eleven.
An agent's session ends. There is no week eleven. The next session is a different context with a different task, and it has no more knowledge of the certbot run than it has of anything else it did not do.
This is not a criticism of agents; it is a description of how they are deployed. They handle the one-off well — reading the docs, getting the flags right, handling the edge case in the DNS challenge. The ongoing part needs two things a coding-agent setup does not normally include: state that outlives the context window, and a scheduler that will wake something up in eleven weeks with that state attached. Both are buildable — a state store the agent writes obligations into, and something outside the agent that reads it on a schedule. Neither comes with the tools by default, so in practice neither exists.
The dangerous part is that the transaction looks like the whole job. The padlock appears. The test passes. Something completed successfully, so the thought stops there.
The whole class, not just certificates
Certificates are the clearest case because the clock is short and the failure is total. But the pattern generalises to anything with an expiry, a renewal, or a host it lives on:
| What an agent set up correctly | What it never agreed to do again |
|---|---|
| A Let's Encrypt certificate | Renew it, or notice when the renewal timer stopped |
| A domain registration or DNS zone | Renew the registration; keep the contact address real |
| An API key, OAuth client, or service account | Rotate it before its expiry; update every consumer |
| A cron entry or systemd timer on a box | Recreate it when the box is replaced |
| A webhook signing secret | Roll it on the schedule the provider requires |
| A cloud credential with a maximum lifetime | Notice the maximum lifetime at all |
Two of those deserve expanding.
The cron entry on a box that got replaced. An agent added a renewal timer to a host. Six weeks later, a different session rebuilt that host from an image, or scaled the group, or moved the service to a new instance type. The new machine is correct in every way that was written down. The timer was not written down — it was typed into a live box. Nothing failed. The renewal simply stopped happening, silently, and the first symptom arrives when the certificate runs out.
The API key with an expiry. Keys that expire are a security improvement and an operational trap. The agent that integrated the service used a key that was valid at the time. Expiry is often a year out, which is far past the horizon of anyone's attention, and the failure mode is not an interstitial in a browser but a background job that starts returning 401 and retrying quietly.
Why nobody has the calendar entry
Calendar entries and runbook lines are made by the person who did the work, during the work, because doing it made them aware of the future obligation. When the work is done by an agent, the awareness is generated inside a session that ends, and the human in the loop reviewed a result — a working site — not a process.
Reviewing a diff tells you what the code does. It does not tell you what external, time-bound facts the code now depends on. A merged pull request that adds an nginx server block does not announce that it has bound your site's availability to a renewal timer running somewhere else on a short clock.
So the obligation exists, it is real, it has a deadline, and it belongs to nobody. This is the same failure that has always produced expired certificates. Agents did not invent it. They industrialised it. The amount of correctly-completed setup work a small team can produce has gone up sharply. The number of people available to carry the obligations it creates has not.
Detect the consequence, because the cause is unbounded
You cannot fix this by asking agents to remember, and you should be sceptical of fixing it by asking humans to be more diligent. Certificates were lapsing for that reason long before any of this was automated.
What works is checking the observable fact rather than the process that was supposed to produce it. We build a monitoring product, so the three checks named below are ours; the principle holds whatever you use to make the measurement.
ssl-cert-expiry connects to the hostname a visitor uses and reads the
certificate that was actually presented. It is indifferent to whether renewal is
automated, whether the timer survived the rebuild, or whether anyone reloaded
nginx afterwards. If the socket is serving something that expires in nine days,
that is the fact, regardless of what the file on disk says.
cert-chain-trust verifies the chain the server sends, in order, to a
trusted root. An agent reconfiguring a proxy can very easily produce a valid
leaf with a missing intermediate. It works in the browser it was tested in and
fails in a client with a colder trust store — which is to say, in your customer's
integration and not on your laptop.
domain-expiry watches the registration underneath all of it, on a much
longer clock. It is the same failure with the volume turned down: a renewal
reminder going to an address that belonged to somebody who left, and when it
lapses there is no name left to present a certificate for.
The one-line version
There is a limit worth stating: this catches the consequence, not the cause. A check tells you the certificate has nine days left. It does not tell you the timer died in a rebuild six weeks ago, and it will not restart it.
That is a real gap and it is still the right trade. The cause is unbounded — there are a great many ways a renewal can stop happening, and each new piece of infrastructure adds a few. The consequence is finite, observable from outside, and requires no privileged access.
So the working assumption should be that anything an agent provisioned with an expiry date will be renewed by nobody. There are other ways to contradict that assumption — declaring the timer in infrastructure-as-code so a rebuild carries it, watching Certificate Transparency logs for a renewal that did not appear — and they are worth having. The cheapest one, and the one that survives all of them failing at once, is a scheduled measurement from outside against the address a visitor actually uses.
Cite this
The HarpyWatch team. “The certificate an agent provisioned and nobody agreed to renew”. The Nest, HarpyWatch, 22 October 2026 UTC. https://harpywatch.com/blog/the-certificate-nobody-agreed-to-renew
More from The Nest
The vulnerabilities agents write fresh
Ask an agent for a login flow and you tend to get a ?next= parameter redirected to whatever it contains. It is the obvious implementation, it is an open redirect, and the remedy was documented years before the model was trained.
What thirty seconds of checking would have caught
A catalogue of small, boring, real failures — a www that resolves nowhere, a redirect that drops to http, a response that is not actually compressed — each one cheap to see from outside.
The debt you take on when a customer tells you first
An outage costs what it costs. Being informed of it by the person it happened to costs something separate, it accrues, and it is charged against the next incident rather than this one.