Certificate Transparency monitoring
A CT log discovery source watches public Certificate Transparency logs for certificates issued for domains you care about — including certificates issued by other teams, other tooling, or an attacker. Every publicly-trusted certificate must be CT-logged, so this catches issuance that never touched CertAutoPilot.
CT monitoring relies on the external crt.sh aggregator, which is frequently rate-limited or down. Because of that the CT source type is hidden from the source-type picker by default. For enumerating certificates behind internal, SNI-routed infrastructure, use an AXFR source instead — it is authoritative and needs no external service. CT monitoring remains the tool for catching publicly-issued shadow-IT certificates on domains you own.
How it works
The CT executor queries crt.sh (the only provider in the current release) once per monitored domain:
- With Include subdomains on, the query covers the apex and every subdomain (
%.example.comwildcard); matching is then re-verified label-safely, soevil-example.comnever matchesexample.com. - Fetches are incremental: the source stores the newest CT log entry timestamp (
last_ct_entry_time) and later runs skip entries logged before it. - Each matching certificate is upserted as a CT observation, deduplicated on (project, provider, provider cert ID, monitored domain) — re-seeing a certificate updates last seen instead of creating a duplicate.
Runs are enqueued as discovery_execute jobs — either by the leader-elected scheduler when the source is due per its schedule interval, or manually via Scan now. If some domains fail (e.g. crt.sh rate-limits), the run completes as partial rather than failing outright.
Configure a CT source
- Go to Discovery → Sources → New → type CT Log.
- Fill in:
- Domains — one per line, maximum 50 per source.
- Include subdomains — default on; off restricts matching to the exact names listed.
- Provider — fixed to
crt.sh. - Allowed issuers — optional list of issuer names you expect (e.g.
Let's Encrypt, your internal CA). Certificates from any other issuer raise a high-severity finding. - Schedule interval — how often the source is polled, in hours; minimum 24.
- Save, then trigger the first run with Scan now if you don't want to wait for the schedule.
Observations
Each observation records the certificate as seen in the log: common name, SANs, issuer, serial number, validity window (not_before/not_after), the CT log entry time, which monitored domain and identifier matched (and whether via CN or SAN), plus first/last seen timestamps.
They surface on the source detail page (Discovery → Sources → source → CT Observations tab), newest log entries first, up to the 500 most recent.
Findings
Two finding types feed the Findings page (scope cert, status open):
| Finding | Severity | Raised when |
|---|---|---|
ct_new_cert | info | A certificate not previously observed appears in CT for a monitored domain. |
ct_unexpected_ca | high | Allowed issuers is configured and the certificate's issuer is not in the list. |
CT alerting is surfaced through discovery findings, not through the notification event pipeline — subscribe your review workflow to the Findings page, not to a notification rule.
Limits & behaviour
| Limit | Value |
|---|---|
| Domains per source | 50 |
| Results per domain per fetch | 500 (truncation is logged — split very busy apexes across sources or rely on incremental catch-up) |
| crt.sh response cap / timeout | 10 MB / 30 s |
| Pause between domain queries | 500 ms (be gentle to crt.sh) |
| Minimum schedule interval | 24 h |
| crt.sh HTTP 429 | Domain marked failed for this run; retried on the next run |
crt.sh itself lags CT log incorporation, and sources poll on an interval of hours — CT monitoring is an audit control, not a real-time alarm. Trigger the source manually from its detail page when you need an immediate sweep.
API
CT sources use the standard discovery-source endpoints; observations have a dedicated listing:
POST /api/v1/projects/{projectId}/discovery-sources
POST /api/v1/projects/{projectId}/discovery-sources/{id}/scan
GET /api/v1/projects/{projectId}/discovery-sources/{id}/ct-observations