A Go library and CLI tool for analyzing X.509 certificate chains. certree shows you every trust path a certificate has -- including cross-signed paths that most tools hide -- and lets you simulate what happens when any certificate in the chain is removed.
Think tree for certificate chains, or dig for TLS trust paths.
When your browser connects to a server, it builds a certificate chain and checks whether it leads to a trusted root. Most tools show you one chain. But certificates can have multiple valid trust paths through cross-signing, and understanding those paths matters when CAs are sunset or trust stores change.
certree builds all possible trust paths, fetches missing intermediates via AIA, and lets you simulate certificate exclusions to see what breaks before you change anything.
go install github.com/timorunge/certree/cmd/certree@latestDownload pre-built binaries for your platform from the releases page.
git clone https://github.com/timorunge/certree.git
cd certree
make buildAnalyze a remote server:
certree github.com[+ ] github.com -- 1 trusted path
`- [+ ] github.com
`- [+ ] Sectigo Public Server Authentication CA DV E36
`- [+ ] Sectigo Public Server Authentication Root E46
Discover all trust paths, including cross-signed chains:
certree --aia-force cloudflare.com[+ ] cloudflare.com -- 4 trusted paths
`- [+ ] cloudflare.com
+- [+ ] WE1 1D:FC:16:05:FB:AD
| +- [+ ] GTS Root R4 76:B2:7B:80:A5:80
| | `- [+ ] GlobalSign Root CA
| `- [+ ] GTS Root R4 34:9D:FA:40:58:C5
`- [+ ] WE1 A2:87:FF:AB:76:2C
`- [+ ] GlobalSign
Four trust paths through different root CAs, collapsed into a merged
tree. When certificates share the same CN (like the two WE1
intermediates), fingerprint prefixes automatically disambiguate them.
The first WE1 (1D:FC...) branches to two variants of GTS Root R4
(one extending to GlobalSign Root CA for backward compatibility). The
second WE1 (A2:87...) reaches GlobalSign directly -- an independent
trust path. If any one root is distrusted, other paths survive.
Simulate removing a certificate and see the impact. All --exclude-*
flags are repeatable and support wildcard patterns:
# Exclude by CN -- see which paths break
certree --exclude-cn "GTS Root R4" --aia-force cloudflare.com
# Exclude by fingerprint -- target a specific certificate variant
certree --exclude-fingerprint "1D:FC:16:*" --aia-force cloudflare.com
# Side-by-side before/after comparison
certree --exclude-cn "GTS Root R4" --compare --aia-force cloudflare.com
# Unified diff view
certree --exclude-cn "GTS Root R4" --diff --aia-force cloudflare.com
# Wildcard patterns
certree --exclude-cn "GTS Root*" --diff --aia-force cloudflare.comAnalyze a local certificate file:
certree cert.pem# Show certificate details
certree --fields all example.com
# JSON output for scripting
certree --format json cert.pem | jq '.[].trust_paths[] | select(.status == "trusted")'
# Pipe from another tool
echo q | openssl s_client -connect example.com:443 -showcerts 2>/dev/null | certree -
# Batch process a list of hosts
certree --batch hosts.txtSee the CLI Reference for the full list of options, output formats, and exit codes.
certree uses sensible defaults for all settings. Pass --config path
for persistent configuration. See
docs/configuration.md for every setting and
its default value.
certree can be used as a Go library:
package main
import (
"context"
"fmt"
"log"
"github.com/timorunge/certree/pkg/certree"
)
func main() {
p := certree.NewParser()
analyzer, err := certree.NewAnalyzer(certree.WithParser(p))
if err != nil {
log.Fatal(err)
}
analysis, err := analyzer.Analyze(context.Background(), "cert.pem")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d certificates in %d trust paths\n",
len(analysis.Certificates), len(analysis.TrustPaths))
for _, cert := range analysis.Certificates {
fmt.Printf(" %s (expired: %v)\n", cert.CommonName(), cert.Metadata().IsExpired)
}
}The docs/ folder has the full documentation:
- CLI Reference -- usage, sources, options, output formats, exit codes
- Library Guide -- using certree as a Go library
- Configuration Reference -- TOML config file format and every setting
- Architecture -- package structure, interfaces, and component interactions
- Certificate Trust Paths -- how TLS chains work, cross-signing, and AIA discovery
- Design Philosophy -- why certree is built the way it is
- Motivation -- why certree exists, the problem it solves, and building software with AI
- Testing -- testing philosophy and property-based testing approach
- Security -- threat model, SSRF protection, and vulnerability reporting
- Hands-on Guide -- step-by-step walkthrough of all certree features
- Contributing -- development setup, quality gates, and how to submit changes
make help # Show all available targets
make check # Run all quality gates (fmt, tidy, vet, lint, test)
make lint # Run golangci-lint
make test # Run tests with race detector
make build # Build static binarySee docs/contributing.md for development setup, quality gates, commit conventions, and the release process.
MIT -- see LICENSE.