Certificate Transparency streaming in Rust
Watches the Chrome- and Apple-trusted Certificate Transparency logs and streams every new SSL/TLS certificate to you over WebSocket or Server-Sent Events. RFC 6962 and static-ct-api logs both work, in one binary.
$ docker run -d -p 8080:8080 \
ghcr.io/reloading01/certstream-server-rust:latest
$ wscat -c ws://localhost:8080/domains-only {"message_type":"certificate_update", "data":["example.com","www.example.com"]}
Features
WebSocket and SSE
Use WebSocket or Server-Sent Events, whichever your client prefers. Both carry the same certificates.
RFC 6962 and static-ct-api
Classic get-entries logs and the newer checkpoint-and-tile static-ct-api logs are watched side by side in one process.
Cross-log deduplication
One certificate usually ends up in several CT logs. The server hashes each one with SHA-256 and sends it once per deduplication window, so your client does not see repeats.
State persistence
Log positions are saved to disk. After a restart or an upgrade each log continues where it stopped instead of starting over.
Connection limits
Optional caps on total connections and on connections per IP address.
Token authentication
Turn on bearer tokens for clients. Tokens are compared in constant time. You can set several of them and change the header name.
Configuration reload
The config file is watched. Settings that support it take effect without a restart.
Log health
Every CT log has its own watcher. Repeated failures move it from healthy to degraded to unhealthy, with retries, exponential backoff and a circuit breaker per log.
Metrics and REST API
Prometheus metrics at /metrics. An optional REST API returns server statistics, CT log status and certificate lookups.
Compatibility
The message format is the one Calidog's certstream-server and certstream-server-go use, so a client only needs a different WebSocket address.
import certstream certstream.listen_for_events(callback, url='wss://your-host:8080/')
# same certificate_update messages, # same all_domains, same leaf_cert wscat -c wss://your-host:8080/
Message types, field names and the leaf_cert shape are unchanged, so a parser written for either of them keeps working. On top of that, this server reads static-ct-api logs and drops duplicates seen across logs. If you only want domain names, /domains-only sends about 100 to 500 bytes per message instead of 2 to 5 KB.
Performance
Two hours against all 45 Chrome- and Apple-trusted logs, default configuration, one subscriber on the domains-only stream, metrics sampled every 30 seconds.
At the median that works out to roughly 36 million certificate updates a day. Each certificate is serialized once and shared with every subscriber through an Arc<PreSerializedMessage>, and with no clients connected the serialization is skipped. Memory is covered in the
API docs.
Support
I develop certstream-server-rust in my spare time and release it under the MIT license. If it is useful to you, a star, a bug report or a word to someone who needs it helps.
GitHub Sponsors is there if you want to support the work.

