Open-source project
SSLMate/certspotter avatar
SSLMate/certspotter

Cert Spotter watches CT logs without a database and parses certificates defensively

Lightweight Certificate Transparency Log Monitor

1,190 stars104 forksGoMPL-2.0

At a glance

What is it?
Cert Spotter is an MPL-2.0 licensed Go tool from SSLMate that monitors Certificate Transparency logs and alerts when a certificate is issued for a domain on your watch list, using a special parser that keeps a certificate unparsed except for its identifiers so an encoding error cannot hide a match. It is stateless by design.
Who is it for?
Cert Spotter fits an organisation that wants to know the moment a certificate is issued for its domains, without running a database or a stack, and it fits a team that has been bitten by a CT monitor missing a certificate because of a parsing failure.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

No database is the unusual part

Cert Spotter is a Certificate Transparency log monitor from SSLMate that alerts you when an SSL/TLS certificate is issued for one of your domains, and the README states the two advantages over other open source CT monitors in one sentence. It is easier to use than other open source CT monitors, since it does not require a database, and it is more robust, since it uses a special certificate parser that ensures it won't miss certificates.

The no database claim is worth unpacking, because it is not a small thing for a log monitor. A CT log is append-only and grows without bound, and a monitor that wants to tell you about a certificate issued ten minutes ago has to either keep a cursor and the certificates it has already seen, or re-read the log from a checkpoint every time it starts.

There is a command line option that shows the design. The -start_at_end option tells certspotter to start monitoring new logs at the end instead of the beginning. This saves significant bandwidth, but you won't be notified about certificates which were logged before you started using certspotter.

So the state is the log position, not a database of certificates. That is what makes the daemon cheap to run and easy to move, and it is also why the option is a trade rather than a free win.

The hosted service by SSLMate is described separately, and it is a superset. It also provides monitoring for expiring and incorrectly-installed certificates, Slack notifications and a web dashboard for tracking all of your certificates. The open source edition is the monitor; the service adds the inventory and the alerting channels.

The detection targets are the four that matter for a defender. Certificates issued to attackers who have compromised your DNS and are redirecting your visitors to their malicious site. Certificates issued to attackers who have taken over an abandoned sub-domain in order to serve malware under your name. Certificates issued to attackers who have compromised a certificate authority and want to impersonate your site. And certificates issued in violation of your corporate policy or outside of your centralized certificate procurement process.

The parser is the security boundary, and null bytes get two identifiers

The Security section describes an explicit adversarial model, and it is the most interesting text in the README.

Cert Spotter assumes an adversarial model in which an attacker produces a certificate that is accepted by at least some clients but goes undetected because of an encoding error that prevents CT monitors from understanding it. To defend against this attack, Cert Spotter uses a special certificate parser that keeps the certificate unparsed except for the identifiers. If one of the identifiers matches a domain on your watchlist, you will be notified, even if other parts of the certificate are unparsable.

That is a design that inverts the usual order. A conventional X.509 parser will fail on a certificate with a malformed extension or an invalid date, and the usual response is to skip it. Here, the failure to parse the rest of the certificate is irrelevant, because the only thing that matters for a monitor is the identifiers.

The concrete example is the null byte case, which is where the parser goes further than the description suggests. If a DNS identifier contains a null byte, Cert Spotter interprets it as two identifiers: the complete identifier, and the identifier formed by truncating at the first null byte. A certificate for example.org\0.example.com will alert the owners of both example.org and example.com. This defends against null prefix attacks, and the reasoning is clear once stated, since a certificate with a null byte in the middle is interpreted differently by different parsers, and a monitor that only reads one interpretation can be told to look the wrong way.

The wildcard handling is the other half of the matching. Cert Spotter understands wildcard DNS names and will alert you if a wildcard certificate might match an identifier on your watchlist, so a watchlist entry for sub.example.com would match certificates for *.example.com.

And the assurance behind the parser is operational. SSLMate continuously monitors CT logs to make sure every certificate's identifiers can be successfully parsed, and will release updates to Cert Spotter as necessary to fix parsing failures. So the parser is kept current by watching the logs rather than by waiting for a bug report, which is a much better failure model for the failure that matters.

Four commands, a watch list file and a hooks directory

The quickstart is four steps, and the configuration is files in a directory rather than a config format.

The first is the install, which requires Go 1.21 or higher.

code
go install software.sslmate.com/src/certspotter/cmd/certspotter@latest

The second is the watch list, a file at $HOME/.certspotter/watchlist with one DNS name per line. To monitor an entire domain tree, including the domain itself and all sub-domains, prefix the name with a dot, for example .example.com. To monitor a single DNS name only, do not prefix it.

The third is where notifications go. Place one or more email addresses in the $HOME/.certspotter/email_recipients file, one per line, and or place one or more executable scripts in the $HOME/.certspotter/hooks.d directory. certspotter will email the listed addresses, which requires your system to have a working sendmail command, and execute the provided scripts when it detects a certificate for a domain on your watch list.

The hooks directory is the interesting part, because it is where a team plugs into their own tooling, an incident management system, a ticketing system, a SIEM. The scripts are a documented interface with their own man page, the certspotter-script(8) man page, so the contract is specified rather than implied.

The fourth is running it as a daemon.

The command set is four binaries, and the README links a man page for each. certspotter itself, certspotter(8) for the command line options and operational details. certspotter-authorize, which tells certspotter about legitimate certificates issued by your certificate authority so that it does not notify you about them, installed with its own go install command and used as certspotter-authorize /path/to/cert.pem. certspotter-script for the script interface. And certspotter-metrics for monitoring certspotter with Prometheus, which the README marks as experimental.

The authorize command solves the false alarm problem, which is the one that kills CT monitors in practice. A company with a managed CA gets a certificate for every domain in the estate, and without a way to say those are expected, the alerting is noise and gets switched off.

It monitors both old and new log APIs, and it audits the log too

Two details in the README describe the scope of the monitoring, and both are easy to miss.

The first is which certificates get detected. In the default configuration, any certificate that is logged to a Certificate Transparency log listed as Qualified, Usable, or ReadOnly in the Google Chrome or Apple log lists will be detected by Cert Spotter. By default, Chrome, Safari, Firefox, and Edge only accept certificates that are logged to at least one such log, with Firefox and Edge using the Chrome log list, so any certificate that works in these browsers will be detected by Cert Spotter.

That is a precise and useful claim. It means the default coverage matches what a browser will actually accept, so the absence of an alert means the absence of a usable certificate, not merely the absence of a certificate in some particular log.

The second is that Cert Spotter monitors both traditional RFC6962 logs and modern static-ct-api logs. The static CT API is the newer interface that lets a client ask a log for the certificates relevant to a domain instead of streaming the whole log, and a monitor that only spoke RFC6962 would be reading a shrinking fraction of the ecosystem.

The third is the auditor role. Cert Spotter is not just a log monitor, but also a log auditor which checks that the log is obeying its append-only property. A future release will support gossiping with other log monitors to ensure the log is presenting a single view.

The gossiping point is the substantive one. A malicious log operator that shows you a different view of the log than everyone else can hide a certificate from you specifically, and cross-checking with another monitor is the mitigation. That it is a future release rather than a shipped one tells you where the project is, and the log list directory in the repository, loglist/, is where the trusted log list lives.

A daily test certificate proves the pipeline end to end

The Testing section describes a self-check that is unusual and clever.

Every day at around 12:05 UTC, a certificate is issued and logged to CT for the DNS name DAY-OF-WEEK.test.certspotter.org. You can add one or more of these DNS names, or .test.certspotter.org, to your watch list to get confirmation that Cert Spotter is working.

The table gives the daily rotation, and it varies two things at once. The issuer alternates between Sectigo, Let's Encrypt and Google, and the key type alternates between RSA and ECDSA.

| DNS Name | Issuer | Key Type | | --- | --- | --- | | monday.test.certspotter.org | Sectigo | RSA | | tuesday.test.certspotter.org | Let's Encrypt | ECDSA | | wednesday.test.certspotter.org | Google | RSA | | thursday.test.certspotter.org | Sectigo | ECDSA | | friday.test.certspotter.org | Let's Encrypt | RSA | | saturday.test.certspotter.org | Google | ECDSA | | sunday.test.certspotter.org | Let's Encrypt | ECDSA |

So this is a conformance test disguised as a monitoring feature. Three different CAs and two different key types means the daily check exercises the certificate parsing across the variations that could break it, and because the certificate is issued by a public CA it goes through the real issuance and logging path rather than a synthetic one.

The practical value for an operator is that a CT monitor can fail silently. If the log list changed, if a log changed its API, if the parser broke on a new certificate shape, the monitor would simply stop noticing anything and nobody would find out. A daily known-positive event with a known name makes that failure loud.

Adding .test.certspotter.org to the watch list means the whole tree, and every day's certificate triggers an alert, which is the point, because the alert is the proof.

Where Cert Spotter is the wrong choice

The first wrong case is a team that needs certificate inventory rather than issuance alerts. The open source edition alerts on new certificates. It does not track what a certificate should be, warn about expiry, or find a certificate installed on the wrong host. The hosted service adds monitoring for expiring and incorrectly-installed certificates, which means the open source tool is not a substitute for it if expiry is the problem you have.

The second wrong case is a team that wants to monitor many logs and many domains with history. The design is deliberately minimal, and the -start_at_end option is the clearest expression of it, you start at the end of the log and you are not told about what came before. A team that needs to query six months of issuance history needs a log monitor with storage, which is the category the README says this tool is not in.

The third wrong case is a team that wants the gossiping verification. The auditor role checks that a log obeys its append-only property, and the cross-monitor gossiping to ensure a single view is described as a future release. Until that ships, the cross-check that defends against a log showing you a different view than everyone else does not exist here, and the hosted service may have it.

The fourth wrong case is a team that wants alerting in the tools they already use. The open source edition emails and runs scripts in a hooks.d directory, which works, but the Slack notifications are a hosted feature. A team that runs everything in Slack and does not want to run a mail server has to build the Slack call themselves, and the sendmail requirement in the quickstart is a small but real operational dependency.

How it differs from the other CT monitors

The comparison worth making is with the general purpose CT log monitors, and the difference in approach is that this one is purpose-built for one job.

A general monitor is a log consumer with a storage layer, a query interface and a user interface. You point it at the logs, it stores what it sees, and you search it. That is the right shape if you want to investigate what happened, to run retrospective queries, or to correlate issuance across a large estate over time.

Cert Spotter has no storage and no query interface. It has a watch list, a cursor and a notifier. The consequence is that the operational surface is tiny, a single binary, a text file of domains and a directory of hook scripts, with no database to migrate, no schema to design and no query tuning. It fits on a small VPS and it can be restarted without losing anything beyond the log position.

The second difference is the parsing, and it is the one that separates this tool from the others. A general monitor that uses a standard X.509 parser will skip a certificate it cannot parse, and a certificate that is accepted by some clients but that a monitor cannot read is exactly the attack the model is built around. Cert Spotter's approach, keeping the certificate unparsed except for the identifiers and alerting on a match regardless, closes that gap. The null byte handling, treating a single identifier as two, is the specific instance of the general principle.

The third difference is the coverage definition. Cert Spotter's default is tied to the Chrome and Apple log lists and the Qualified, Usable and ReadOnly states, which means the default matches what browsers accept. A general monitor that streams every log it can reach may see more, but what it sees is not the same as what is usable, and the alert volume goes up without the signal improving.

The fourth difference is the operational model. This is a daemon that watches and tells you, and the hosted version adds the inventory and the dashboards. The split is a business decision, but it also means the open source edition is the one you run when you want a small, sharp alerting tool, and the service is the one you buy when you want a certificate management system.

Editorial conclusion

Cert Spotter fits an organisation that wants to know the moment a certificate is issued for its domains, without running a database or a stack, and it fits a team that has been bitten by a CT monitor missing a certificate because of a parsing failure. It does not fit a team that needs expiring certificate monitoring, Slack notifications or a certificate dashboard, because those are the hosted service's features, and it does not fit a team that needs a full log auditor across many logs without reading the log list and gossiping support notes. Before adopting it, add the daily test.certspotter.org name to your watch list to confirm the pipeline works, and note that the module retracts v0.19.0 for containing serious bugs, with the last push on 2026-10-09.

Frequently asked questions

What is Cert Spotter and what does it detect?

It is a Certificate Transparency log monitor from SSLMate that alerts you when an SSL/TLS certificate is issued for one of your domains. It detects certificates issued to attackers who compromised your DNS, certificates issued for abandoned sub-domains taken over to serve malware, certificates issued by a compromised certificate authority, and certificates issued outside your corporate procurement policy.

How do I install and set up Cert Spotter?

With Go 1.21 or higher, run go install software.sslmate.com/src/certspotter/cmd/certspotter@latest. Create $HOME/.certspotter/watchlist with one DNS name per line, prefixing a domain with a dot to monitor the whole tree. Put email addresses in $HOME/.certspotter/email_recipients and scripts in $HOME/.certspotter/hooks.d, then run certspotter as a daemon, optionally with -start_at_end.

How does Cert Spotter avoid missing certificates?

It assumes an adversarial model where an attacker produces a certificate that some clients accept but that a CT monitor cannot understand because of an encoding error. The parser keeps the certificate unparsed except for the identifiers, so a match on a watched domain notifies you even if other parts of the certificate are unparsable, and a DNS identifier containing a null byte is treated as two identifiers.

Which CT logs does Cert Spotter monitor?

In the default configuration, any certificate logged to a log listed as Qualified, Usable or ReadOnly in the Google Chrome or Apple log lists is detected, which matches what Chrome, Safari, Firefox and Edge accept. It monitors both traditional RFC6962 logs and modern static-ct-api logs, and it also audits whether a log obeys its append-only property.

How can I confirm Cert Spotter is actually working?

Every day at around 12:05 UTC a certificate is issued and logged for DAY-OF-WEEK.test.certspotter.org, rotating through the issuers Sectigo, Let's Encrypt and Google and between RSA and ECDSA keys. Add one of those names, or .test.certspotter.org, to your watch list and the daily alert confirms the pipeline works end to end.

Official sources

  1. Issues
  2. License: MPL-2.0
  3. Project website
  4. README
  5. SSLMate/certspotter on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sslmate-certspotter.svg)](https://hysenlabs.com/projects/sslmate-certspotter)

Was this useful?