Loading repository data…
Loading repository data…
SCGIS-Wales / repository
A Rust CLI and MCP server for X.509 certificate analysis, format conversion, and key verification. Reads certificates from PEM files or HTTPS endpoints. Validates TLS connections, checks revocation status, converts between PFX and PEM formats and integrates with AI-powered IDEs via the Model Context Protocol (MCP) and Vault.
# Install via Homebrew
brew tap SCGIS-Wales/homebrew-tap https://github.com/SCGIS-Wales/homebrew-tap.git
brew install dcert
# Analyze a live HTTPS endpoint (bare hostname or full URL)
dcert api.example.com
dcert https://www.google.com
# Read PEM from a pipe
cat certificate.pem | dcert
# Check certificate expiry (CI/CD gate)
dcert https://your-api.com --expiry-warn 30
# Convert PFX to PEM
dcert convert pfx-to-pem client.pfx --password secret --output-dir ./certs
# Verify a private key matches a certificate
dcert verify-key cert.pem --key private.key
# Auto-discover and verify all cert/key pairs in a directory
dcert verify-key
# Create a new CSR with RSA 4096 key
dcert csr create --cn api.example.com --org "My Corp" --country GB
# Validate a CSR for compliance
dcert csr validate my-cert.csr
# Issue a TLS certificate from HashiCorp Vault PKI
dcert vault issue --cn www.example.com --role my-role
# Renew a certificate stored in Vault KV
dcert vault renew secret/certs/www-example-com --role my-role
Homebrew is the recommended installation method. On Linux it builds from source, which avoids glibc compatibility issues and works on Ubuntu 22.04 and later.
brew tap SCGIS-Wales/homebrew-tap https://github.com/SCGIS-Wales/homebrew-tap.git
brew install dcert
Note: If you don't have Homebrew on Linux, install it first:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Download from the Releases page. Each release includes dcert (CLI) and dcert-mcp (MCP server). Prebuilt Linux binaries require Ubuntu 22.04 (glibc 2.35) or later.
curl -L https://github.com/SCGIS-Wales/dcert/releases/latest/download/dcert-x86_64-unknown-linux-gnu.tar.gz | tar xz
chmod +x dcert dcert-mcp
sudo mv dcert dcert-mcp /usr/local/bin/
Install with Chocolatey:
choco install dcert
Or pip install dcert (the win_amd64 wheel bundles dcert.exe and dcert-mcp.exe), or download the dcert-x86_64-pc-windows-msvc.zip archive from the Releases page and add the extracted .exe files to your PATH.
Note: the Windows build links a vendored OpenSSL that has no system trust store. If certificate verification fails because no CA roots are found, set
SSL_CERT_FILEto a CA bundle (e.g. one exported from your organization or acacert.pem).
git clone https://github.com/SCGIS-Wales/dcert.git
cd dcert
cargo build --release
# Binaries: target/release/dcert and target/release/dcert-mcp
docker pull ghcr.io/scgis-wales/dcert:main
# CLI
docker run --rm ghcr.io/scgis-wales/dcert:main https://www.google.com
# Local PEM file
docker run --rm -v "$PWD:/data" ghcr.io/scgis-wales/dcert:main /data/cert.pem
# MCP server
docker run --rm -i --entrypoint dcert-mcp ghcr.io/scgis-wales/dcert:main
dcert uses subcommands to organize its features. The check subcommand is the default and can be omitted:
dcert <targets> [OPTIONS] # Certificate analysis (default, same as 'dcert check')
dcert csr create [OPTIONS] # Create a CSR and private key
dcert csr validate <CSR_FILE> # Validate a CSR for compliance
dcert convert <MODE> [OPTIONS] # Format conversion (PFX/PEM/keystore/truststore)
dcert verify-key <target> --key <KEY> # Key-certificate matching (single pair)
dcert verify-key [--dir <DIR>] # Auto-discover and verify all cert/key pairs
dcert vault issue [OPTIONS] # Issue a TLS certificate from Vault PKI
dcert vault sign [OPTIONS] # Sign a CSR using Vault PKI
dcert vault revoke [OPTIONS] # Revoke a certificate in Vault PKI
dcert vault list [OPTIONS] # List certificates issued by Vault PKI
dcert vault store [OPTIONS] <PATH> # Store cert+key in Vault KV
dcert vault validate <PATH> # Validate a certificate in Vault KV
dcert vault renew <PATH> [OPTIONS] # Renew a certificate in Vault KV
Analyze TLS certificates from PEM files or HTTPS endpoints. The check keyword is optional -- dcert https://example.com and dcert check https://example.com are equivalent.
# Fetch and analyze certificates from HTTPS
dcert https://www.google.com
# Bare hostname (auto-prepends https://)
dcert api.example.com
# Analyze a local PEM file
dcert certificate.pem
# Read PEM data from stdin (pipe)
cat certificate.pem | dcert
echo "<base64-pem>" | base64 --decode | dcert
cat certificate.pem | dcert -
# Multiple targets
dcert https://www.google.com https://github.com cert.pem
# Pipe target names from stdin (one per line)
echo -e "https://google.com\nhttps://github.com" | dcert -
# JSON or YAML output
dcert https://example.com --format json
dcert https://example.com --format yaml
# SHA-256 fingerprints and certificate extensions
dcert https://example.com --fingerprint --extensions
# Expiry warning (exit code 1 if expiring within 30 days)
dcert https://example.com --expiry-warn 30
# OCSP revocation check
dcert https://example.com --check-revocation
# Compare certificates between two targets
dcert --diff https://staging.example.com https://prod.example.com
# Monitor certificates every 60 seconds
dcert --watch 60 https://example.com
# Export certificate chain to PEM file
dcert https://www.google.com --export-pem chain.pem
# Export excluding expired certificates
dcert https://www.google.com --export-pem chain.pem --exclude-expired
# Sort by expiry date
dcert certificates.pem --sort-expiry asc
# Only show expired certificates
dcert certificates.pem --expired-only
# Compliance report (CA/B Forum Baseline Requirements)
dcert https://example.com --compliance
dcert certificate.pem --compliance
# Compliance report in JSON (for CI/CD)
dcert https://example.com --compliance --format json
Every check reports whether the certificate chain anchors to a publicly
trusted root CA, a private PKI, or is self-signed — answering "is this
issued by a real public CA, or a private/self-signed one?" This runs by default.
# Classification appears in the "Root CA trust" block (pretty) and the
# "root_trust" object (JSON/YAML)
dcert https://www.google.com
dcert https://example.com --format json # see .root_trust
# Skip it (byte-stable legacy output)
dcert https://example.com --no-trust-check
The classification is one of:
| Classification | Meaning |
|---|---|
publicly_trusted | Chain verifies up to a root in the embedded Mozilla/CCADB root set |
private_pki | Chain terminates in a private (non-public) root CA |
self_signed | A single self-signed certificate, not issued by any CA |
incomplete | Chain neither reaches a public root nor presents a self-signed root (an issuer is missing) — try --resolve-issuers |
How "publicly trusted" is defined. The authoritative source is the
Mozilla/CCADB root set, embedded at build time via the webpki-root-certs
crate. CCADB is the shared database behind the Mozilla, Microsoft, Apple and
Google root programs, so DigiCert, Amazon/AWS, Google Trust Services, Microsoft
and Apple public TLS roots, GlobalSign, Sectigo, Let's Encrypt, etc. are all
included. Classification is a local cryptographic verification — no network
is used — so it stays fast across 50+ certificates with no per-host timeouts. A
private root that merely shares a Distinguished Name with a public one cannot
produce a false positive, because the signature must validate against an
embedded public key. Certificate expiry is ignored for this verdict (dcert
reports expiry separately).
Each certificate that is itself a recognized public root carries an
is_public_root: true attribute in JSON/YAML (usually absent, since servers
don't send the root).
Optional network probe (--resolve-issuers). For incomplete or
private_pki results you can follow the certificate's AIA "CA Issuers" URLs to
fetch missing issuer certificates — completing the chain (which can flip an
incomplete result to publicly_trusted) and confirming whether a private CA
backend is reachable (private_backend_reachable). It is off by default.
# Complete a chain whose server omitted the intermediate
dcert https://example.com --resolve-issuers
# Keep the timeout short when probing many private CAs
dcert - --resolve-issuers --issuer-timeout 2 < hosts.txt
--resolve-issuers honours the standard forward-proxy environment variables
(http_proxy/https_proxy/no_proxy, see Proxy and Timeout
Configuration) and uses the short
--issuer-timeout (default 2s) so large batches fail fast. Unlike the OCSP
path, it intentionally does not block private/internal IPs — private-PKI AIA
endpoints legitimately live on internal hosts, which is exactly what this flag
exists to reach. It is gated behind this explicit opt-in.
Refreshing the public root set. --refresh-public-roots fetches the latest
Mozilla/CCADB bundle from https://curl.se/ca/cacert.pem (over the proxy layer)
and unions it into the embedded set for that run, so coverage can stay current
between releases.
# Require TLS 1.3
dcert --min-tls 1.3 https://example.com
# Force TLS 1.2 only
dcert --min-tls 1.2 --max-tls 1.2 https://example.com
# Specific TLS 1.2 ciphers
dcert --cipher-list "ECDHE+AESGCM:CHAC