Skip to content
Making Lancert a Better ACME Client

Making Lancert a Better ACME Client

July 27, 2026

When I first introduced Lancert, it answered a fairly specific question:

Can publicly trusted TLS certificates be issued for services running on private networks, without exposing those services to the public Internet?

Once that part became reliable, the interesting questions changed.

Lancert already knew how to issue certificates, cache them and renew them automatically. Users remained responsible for deploying a replacement certificate, either manually or through their own automation.

For a homelab or another private environment, that is often a perfectly reasonable operational model. Replacing a certificate every couple of months is rarely an emergency.

Still, the fact that the operational requirements are modest does not mean the client should stop making better decisions.

One of those decisions concerns renewal.

Not how to renew a certificate, but who should decide when renewal happens.

Local renewal policies

Most ACME clients have traditionally answered that question with a local policy.

Renew thirty days before expiration.

Renew after two thirds of the certificate lifetime.

Renew when fewer than a certain number of days remain.

These strategies are simple, predictable and generally work well.

They also require every client to make the decision independently, using only the information available locally.

A single ACME client sees its own certificates.

The Certificate Authority sees the wider system.

It can observe renewal traffic across its infrastructure, spread that traffic over time and react when certificates need to be replaced earlier than usual.

That makes the CA better positioned to suggest when renewal should happen.

Letting the CA decide

ACME Renewal Information, or ARI, provides a standard way to do that.

For each certificate, the ACME server can publish a suggested renewal window. The client chooses a random point within that window and renews the certificate once that time is reached.

The client remains responsible for performing the renewal reliably.

What changes is where the timing decision originates.

Rather than permanently relying on a fixed local policy, the client can cooperate with the CA and use information that reflects the state of the wider certificate ecosystem.

This allows the CA to distribute renewal traffic more evenly and to request earlier replacement of specific certificates when necessary.

Let’s Encrypt also exempts qualifying ARI renewals from its issuance rate limits when the replacement order correctly identifies the previous certificate and is submitted during the suggested renewal window.

That was not the primary motivation for adding ARI to Lancert. The service targets private networks and its expected certificate volume is modest.

It is still a useful consequence of following the protocol correctly.

Improving the client, not the interface

Adding ARI did not change how Lancert is used.

There are still no accounts.

No API keys.

No option for selecting a renewal strategy.

The change lives entirely inside the existing certificate lifecycle.

Lancert retrieves renewal information from the Certificate Authority, selects a time within the suggested window and persists that decision alongside the existing certificate metadata.

The existing renewal process then acts on it when the certificate becomes eligible.

ARI is also treated as additional information, not as a hard dependency.

If renewal information is unavailable, cannot be retrieved or cannot be validated, Lancert falls back to its existing renewal policy.

The objective is not to make renewal depend on ARI.

It is to make a better decision whenever better information is available.

There is no separate scheduler dedicated to ARI, no new public API and no event ledger recording every renewal decision.

The existing renewal engine remains responsible for the work. It simply has more context.

Issuance is not deployment

Obtaining a replacement certificate does not invalidate the previous one.

After a new certificate has been issued, the existing certificate remains valid until it expires naturally or is explicitly revoked.

Issuance and deployment are therefore separate moments in the certificate lifecycle.

Lancert can obtain a replacement certificate when the CA recommends it, while users remain free to deploy it when appropriate for their environment.

For some homelabs, that may still mean replacing the certificate manually every few months.

For others, it may mean using a small script to download the current certificate and reload the relevant web server.

The documentation now includes a minimal example of that process, but deployment remains deliberately outside Lancert’s control.

Making the service observable

While improving the certificate lifecycle, I realised that Lancert itself was difficult to observe.

The service could issue, cache and renew certificates, but there was no straightforward way for someone using it to understand how it was performing.

That led to the public status page.

It is not an administration dashboard. There are no user accounts to administer and no individual resources to inspect.

Its purpose is to expose a small set of aggregate operational metrics:

  • how many certificates have been issued;
  • how many have been renewed;
  • how many certificates are currently active;
  • how effectively the cache is serving requests;
  • how often renewal decisions are being guided by ARI.

These numbers make the behaviour of the service visible.

Users do not have to rely entirely on trust to know whether certificates are being issued, renewals are taking place or the service is being actively used.

The metrics are intentionally best effort. A failure to record or update a metric must never cause certificate issuance or renewal to fail.

Certificate handling remains the primary responsibility of the service. Observability is secondary.

Observability without user tracking

Making the service observable does not require tracking the people using it.

The status page exposes aggregate operational information only.

Lancert does not need a per-user activity history, a per-certificate analytics trail or a record of which client requested which hostname in order to explain how the service is performing.

Only the information required to operate the service and protect it against abuse should be retained.

The goal is transparency about the system, not visibility into its users.

Observability should not require user tracking.

Staying small

From the outside, Lancert still works as it did before.

A certificate is requested.

The service issues or retrieves it from the cache.

Eventually, it renews it.

Deployment remains under the user’s control.

Internally, however, the service now makes a better renewal decision whenever the Certificate Authority provides enough information to do so. When that information is unavailable, it retains a predictable fallback.

Its behaviour is also easier to inspect, without collecting unnecessary data about the people using it.

No new workflow was introduced.

No new concept was added for users to learn.

Lancert simply became a better ACME client.

References