certs CLI
Run locally without us. No middleman. No rate limits. Same engine as certs.lol.
MITGo<5s scans
Install
# Homebrew
brew install yokedotlol/tap/certs
# Or one-liner
curl -sSL https://certs.lol/install.sh | bash
# Or download from GitHub Releases
curl -sL https://github.com/yokedotlol/certs-lol/releases/latest/download/certs_darwin_arm64.tar.gz | tar xz
sudo mv certs /usr/local/bin/
Quick Start
# Scan a domain
certs stripe.com
# JSON output (default when piped)
certs stripe.com | jq
# Grade only
certs stripe.com -g
# CI gate — fail if below A
certs api.prod.example.com --assert "min-grade A"
# Compliance check
certs payments.prod --profile pci
# Scan internal hosts (private IPs allowed by default)
certs internal-api.corp.local
# Mail server TLS
certs --mx example.com
Three Modes
| Mode | When | Use |
| Pretty | TTY (default) | Human-readable, colored tree output |
| JSON | Piped / --json | Machine-readable, matches certs.lol API |
| Assert | --assert | CI/CD gating with pass/fail reports |
Assertion Rules
Compose multiple assertions to gate deploys. All must pass — any failure exits non-zero.
certs api.prod \
--assert "min-grade A" \
--assert "no-tls1.0" \
--assert "cert-days 30" \
--assert "no-insecure-ciphers"
Grade
min-grade <G> | Grade must be ≥ threshold (A+, A, B, C, D, F) |
Certificate
cert-days <N> | ≥ N days until expiry |
cert-type <type> | Validation level (DV, OV, EV) — minimum match |
cert-key-min <bits> | Minimum key size in bits |
cert-key-type <type> | Key type (RSA, ECDSA, Ed25519) |
cert-san <pattern> | At least one SAN must match glob |
cert-issuer <pattern> | Issuer must contain string |
cert-chain-valid | Chain must be valid |
cert-has-scts | CT SCTs must be present |
Protocol
min-tls <ver> | Minimum supported TLS version |
max-tls <ver> | Maximum supported TLS version |
no-tls1.0 | TLS 1.0 must not be supported |
no-tls1.1 | TLS 1.1 must not be supported |
has-tls1.3 | TLS 1.3 must be supported |
has-pq | Post-quantum key exchange required |
has-ech | Encrypted Client Hello required |
Ciphers
no-insecure-ciphers | Zero insecure ciphers (RC4, NULL, EXPORT, anon) |
no-weak-ciphers | Zero weak ciphers (3DES, CBC-no-FS, RSA-kex) |
max-weak-ciphers <N> | At most N weak ciphers |
min-strong-ciphers <N> | At least N strong ciphers |
has-forward-secrecy | At least one FS cipher present |
Security & DNS
has-hsts | HSTS header required |
hsts-min-age <secs> | HSTS max-age minimum |
has-hsts-preload | HSTS preload directive required |
has-dnssec | DNSSEC required |
has-caa | CAA records required |
has-ocsp-stapling | OCSP stapling required |
Compliance
compliant-pci | PCI DSS 4.0 transport requirements |
compliant-nist | NIST SP 800-52r2 requirements |
compliant-hipaa | HIPAA transport requirements |
Mail
has-starttls | Server must offer STARTTLS upgrade |
Profiles
Named bundles for common use cases:
# Production baseline
certs api.prod --profile production
# PCI DSS compliance
certs payments.prod --profile pci
# Maximum strictness
certs cdn.prod --profile strict
| Profile | Assertions |
production | min-grade A, no-tls1.0, no-tls1.1, no-insecure-ciphers, cert-days 14, has-hsts |
staging | min-grade B, no-insecure-ciphers, cert-days 7 |
strict | min-grade A+, no-tls1.0/1.1, no-weak/insecure, has-tls1.3, has-pq, has-forward-secrecy, cert-days 30, has-hsts, has-hsts-preload, has-dnssec, cert-has-scts |
pci | compliant-pci, no-insecure/weak, has-tls1.3, cert-days 30, has-hsts |
nist | compliant-nist, has-tls1.3, no-tls1.0/1.1, cert-key-min 256 |
hipaa | compliant-hipaa, cert-days 30, no-insecure-ciphers, has-hsts |
baseline | min-grade C, no-insecure-ciphers, cert-days 7, cert-chain-valid |
Profiles and --assert compose freely:
certs cdn.prod --profile production --assert "has-pq"
Config File
Check a .certs.yaml into your repo for team-wide defaults:
# .certs.yaml
profile: production
assertions:
- cert-type OV
- cert-issuer DigiCert
- has-pq
- hsts-min-age 63072000
targets:
- api.example.com
- cdn.example.com
- payments.example.com
# Uses .certs.yaml from current directory
certs
# Or specify config
certs --config path/to/.certs.yaml
Lookup order: --config flag → .certs.yaml in cwd → ~/.config/certs/config.yaml
Bulk Scanning
# Scan from file (auto-concurrent above 3 targets)
certs --file domains.txt --out results/
# With assertions
certs --file production-domains.txt --profile production --out results/
# Control concurrency
certs --file domains.txt --workers 20 --quiet
Writes per-target JSON files and a _summary.json with aggregate results.
STARTTLS & Mail
# Auto-detect from port
certs mail.example.com --port 25 # SMTP STARTTLS
certs mail.example.com --port 587 # SMTP STARTTLS
certs mail.example.com --port 993 # IMAP implicit TLS
# Explicit protocol
certs mail.example.com --port 2525 --starttls smtp
# MX lookup — resolve and scan all mail servers
certs --mx example.com --assert "has-tls1.3"
CI Examples
GitHub Actions
name: TLS Check
on: [push]
jobs:
tls:
runs-on: ubuntu-latest
steps:
- name: Install certs
run: |
curl -sL https://github.com/yokedotlol/certs-lol/releases/latest/download/certs_linux_amd64.tar.gz | tar xz
sudo mv certs /usr/local/bin/
- name: Check TLS
run: certs api.example.com --profile production
GitLab CI
tls-gate:
script:
- curl -sL https://github.com/yokedotlol/certs-lol/releases/latest/download/certs_linux_amd64.tar.gz | tar xz
- ./certs api.example.com --profile production
only:
- main
Exit Codes
0 | Scan succeeded, all assertions passed |
1 | Scan succeeded, assertion(s) failed |
2 | Usage error (bad flags, invalid assertion) |
3 | Scan/connection error |
Flags
| Flag | Short | Default | Description |
--json | -j | auto | Force JSON output |
--table | -t | auto | Force pretty output |
--grade | -g | — | Print only the letter grade |
--assert | -a | — | Assertion rule (repeatable) |
--profile | -P | — | Named assertion profile |
--config | -c | .certs.yaml | Config file path |
--port | -p | 443 | Target port |
--timeout | — | 15s | Connection timeout |
--starttls | — | — | Force STARTTLS protocol |
--probe-only | — | false | Skip enrichment |
--no-private | — | false | Block private/reserved IPs |
--mx | — | — | Resolve MX and scan mail servers |
--file | -f | — | Read targets from file |
--out | -o | — | Write results to directory |
--workers | -w | 10 | Concurrent workers (bulk) |
--quiet | -q | false | Suppress progress |
Source
github.com/yokedotlol/certs-lol — MIT licensed.