What is certificate transparency?

10 min readUpdated

Certificate transparency (CT) is a system of public, append-only logs of issued TLS server certificates, defined in RFC 6962 [1]. The logs do not stop a wrong certificate from being issued. They make sure that interested parties, particularly those named in certificates, can detect it [1]. In CT-enforcing versions of Chrome and on Apple platforms, a publicly trusted certificate that does not meet the vendor's CT policy fails validation [2][3]. A certificate for your domain that is meant to work there, issued by any CA and for any reason, is therefore in public logs where you can find it. Certificate transparency is one of the terms in the SSL and TLS glossary.

Defined in
RFC 6962, CT 1.0; RFC 9162, CT 2.0, obsoletes it [4]
Proof of logging
a signed certificate timestamp (SCT) [1]
SCT delivery
in the certificate, in a TLS extension, or in a stapled OCSP response [1]
Enforced by
Chrome and Apple platforms, for publicly trusted certificates [2][3]
Chrome error
ERR_CERTIFICATE_TRANSPARENCY_REQUIRED, code -214 [5]
Exposes
every domain name in a logged certificate [6]

How certificate transparency logs work

A log is a single, ever-growing, append-only Merkle tree of certificates [1]. Anyone can submit a certificate, as long as its chain leads to a root the log accepts, and the RFC expects certificate owners or their CAs to do it [1]. The log answers a submission at once with a signed certificate timestamp (SCT): its promise to add the certificate to the tree within a fixed time, the maximum merge delay [1]. At intervals it appends the new entries and signs the root of the tree. With a Merkle tree, any version of the log can be shown to contain every entry of an earlier one, and a log that shows different things to different people can be caught by comparing tree roots [1].

The RFC names the roles around a log. Monitors fetch every new entry and watch for certificates of interest; auditors check that a certificate whose SCT they saw really appears in the log [1]. The logs do not decide whether a certificate was issued correctly. That is left to interested parties who watch them, such as domain owners [1].

An entry stays once it is in. A mistaken issuance leaves a trace even if the certificate is later revoked; revocation is a separate mechanism, covered with the other SSL certificates topics.

Precertificates: how SCTs get inside a certificate

A CA can log a certificate before it issues it. It submits a precertificate: the future certificate with an added critical poison extension, OID 1.3.6.1.4.1.11129.2.4.3, so that no standard client can validate it [1]. The SCTs the logs return can go into the final certificate as an extension with OID 1.3.6.1.4.1.11129.2.4.2 [1]. A test with a home-made authority, Example Test CA, and OpenSSL 3.0.13 shows the poison at work:

$ openssl x509 -in precert.pem -noout -text | grep -A1 "CT Precertificate Poison"
            CT Precertificate Poison: critical
                NULL
$ openssl verify -CAfile ca.pem precert.pem
CN = www.example.com
error 34 at 0 depth lookup: unhandled critical extension
error precert.pem: verification failed

The same certificate without the extension verifies as OK against the same test authority. OpenSSL has a name for each of the four CT object identifiers of RFC 6962:

CT object identifiers in RFC 6962 and their names in OpenSSL output
OIDRole in RFC 6962Name in OpenSSL output
1.3.6.1.4.1.11129.2.4.2SCT list embedded in the certificateCT Precertificate SCTs
1.3.6.1.4.1.11129.2.4.3poison extension of a precertificateCT Precertificate Poison
1.3.6.1.4.1.11129.2.4.4extended key usage of a precertificate signing certificateCT Precertificate Signer
1.3.6.1.4.1.11129.2.4.5SCT list in a stapled OCSP responseCT Certificate SCTs

Which RFC is in force: 6962 or 9162?

RFC 9162 describes Certificate Transparency version 2.0 and obsoletes RFC 6962 [4]. Both are Experimental RFCs, not Internet Standards Track specifications [1][4]. Version 2.0 changes the data formats: precertificates become CMS objects instead of X.509 certificates, the poison extension and precertificate signing certificates go away, each log is identified by an OID, and the signed_certificate_timestamp TLS extension is replaced by transparency_info [4]. The structures are incompatible, so a log is either v1 or v2, and a v2 log cannot issue a valid v1 SCT [4].

The browser policies point to version 1. Chrome admits logs that conform to RFC 6962 or to the static-ct-api v1.1.0 specification [2], and Apple requires at least one SCT from a log compliant with RFC 6962 [3]. On paper RFC 9162 has replaced RFC 6962, yet neither policy names RFC 9162.

What Chrome and Apple require

Both vendors check SCTs while validating a certificate, and both count them by log and by log operator. The table follows the published policies [2][3].

What Chrome and Apple require, rule by rule
RuleChromeApple
Applies topublicly trusted TLS certificates, in CT-enforcing versions [2]publicly trusted TLS server authentication certificates [3]
Embedded SCTs, lifetime of 180 days or lessfrom at least 2 distinct logs that are Qualified, Usable, ReadOnly or Retired at the time of check [2]from 2 distinct once or currently approved logs, at most 1 per log operator counted [3]
Embedded SCTs, longer lifetimefrom at least 3 distinct logs that are Qualified, Usable, ReadOnly or Retired at the time of check (more than 180 days) [2]from 3 distinct once or currently approved logs, at most 2 per log operator counted (181 to 398 days) [3]
Log statusat least one embedded SCT from a log that is Qualified, Usable or ReadOnly at the time of check [2]at least one embedded SCT from a currently approved log [3]
Log operatorsat least two SCTs from distinct operators [2]the per-operator maximum above [3]
SCTs sent during the handshakeat least 2 via the TLS extension, from Qualified, Usable or ReadOnly logs of distinct operators; from a stapled OCSP response only in versions before 148 [2]at least 2 from currently approved logs, one of them via the TLS extension or OCSP stapling [3]
Certificate that does not complyfails to validate [2]the TLS connection fails [3]

ERR_CERTIFICATE_TRANSPARENCY_REQUIRED in Chrome

ERR_CERTIFICATE_TRANSPARENCY_REQUIRED is Chrome's network error -214. Chromium defines it as a connection where Certificate Transparency was required, but the server did not provide CT information that complied with the policy [5]. Chrome's own description of the error reads: "The server's certificate was not disclosed via Certificate Transparency." [5]

The cause sits on the server side: neither the certificate nor what the server sends with it, in the TLS extension or a stapled OCSP response, carries SCTs from certificate transparency logs that meet the rules above. Chrome's guidance mentions two ways this can happen. A CA may have an infrastructure issue, and changes in the CT ecosystem may make the CT information in an existing certificate lose validity before the certificate expires [6].

Checking a certificate for SCTs

To see whether a certificate carries embedded SCTs, print it and look for the extension:

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -text | grep -A3 "CT Precertificate SCTs"

Each embedded SCT prints as a Signed Certificate Timestamp block with a log ID and a timestamp. No output means no embedded SCTs. SCTs sent in the TLS extension do not appear here, because the command prints only the certificate. The listing shows presence, not compliance: a test certificate with a made-up SCT, a fake log ID and a dummy signature prints the same block without complaint. Whether the SCTs satisfy the policy is decided by the browser, which checks the logs behind them [2].

Fixing it as the site owner

Chrome's guidance gives the site owner two routes [6]:

  1. Contact the CA's support. The CA will most likely need to replace the certificate with a new one that properly supports CT. SCTs embedded in the certificate are the way Chrome prefers.

  2. If the existing SCTs lost validity, you may be able to send new SCTs in the TLS handshake, through the TLS extension. This needs server configuration, and Chrome does not recommend it for most sites, because someone has to monitor the CT ecosystem constantly.

Certificates from a CA you installed yourself, one that is not and never was publicly trusted, are outside the rule: the Chrome CT policy applies only to publicly trusted CAs, and certificate transparency logs do not accept certificates from manually installed ones [6][7]. On managed devices an administrator can switch enforcement off for listed domains with the CertificateTransparencyEnforcementDisabledForUrls policy [7]. That setting covers an organisation's own machines, not the visitors of a public site. Other certificate errors that Chrome shows, each with its own code, are in the SSL certificate errors section.

Why it matters for a site owner

For a site owner, certificate transparency cuts both ways.

Unexpected issuance becomes visible

This is the case RFC 6962 describes: a monitor watching certificate transparency logs for your names can find a certificate issued for your domain that you did not request [1]. It can show up before the certificate is ever deployed, since a CA may log the precertificate before issuance [1]. Chrome's documentation says CT has detected issues at a large number of CAs, many of which the CAs themselves were not aware of [6]. Browsers once offered a stricter answer, certificate pinning for websites, and dropped it because one mistake could lock visitors out; public logs detect the problem instead of blocking it. Restricting issuance is a separate tool: a CAA record in DNS lets the domain holder name the CAs authorized to issue for the domain, as defined in RFC 8659 [8].

Your names become public as you use them

Certificate transparency logs make the full contents of a certificate public: every domain it is for and, above domain validation, the organisation it is affiliated with [6]. Internal-sounding names on a public certificate are published by the act of issuing. A name you would rather not announce should either stay out of publicly trusted certificates, served with a private CA that only your organisation's devices trust [7], or sit under a wildcard such as *.example.com, which is logged too but does not list each host [6]. That is a decision to make before issuance rather than after.

It surprises teams who assume an unpublished name is effectively private. It was never private; it was merely unlisted, and issuing a certificate lists it.

Certificates themselves are under certificates, automated issuance under ACME, the header that keeps browsers on HTTPS under HTTP Strict Transport Security (HSTS), the key pairs behind certificates under public key cryptography in TLS, and the rest of the vocabulary in this glossary. Why the certificates in these logs are still called SSL certificates when the protocol is TLS is covered under the difference between SSL and TLS. Where Windows keeps them on a computer is explained under the Windows certificate store for SSL certificates. The certificate CN has a page of its own.

Sources

  1. RFC 6962, Certificate Transparency: §1, §3, §3.1, §3.3, §5.3, §7.2.

  2. Chrome Certificate Transparency Policy, with the Chrome CT Log Policy, section Log API Specification Requirements.

  3. Apple's Certificate Transparency policy.

  4. RFC 9162, Certificate Transparency Version 2.0: Abstract, §1.3, Appendix A.

  5. Chromium: net/base/net_error_list.h (CERTIFICATE_TRANSPARENCY_REQUIRED, -214) and components/ssl_errors_strings.grdp (IDS_CERT_ERROR_CERTIFICATE_TRANSPARENCY_REQUIRED_DESCRIPTION).

  6. Certificate Transparency for Site Operators, Chrome.

  7. Certificate Transparency for Enterprises, Chrome: Locally-trusted CAs, Private Domain Names, Enterprise Policies.

  8. RFC 8659, DNS Certification Authority Authorization (CAA) Resource Record: Abstract.