Certificate discovery agent for CertForge. Finds TLS certificates across your infrastructure and reports them to CertForge for governance, expiry tracking, and compliance.
Most certificate problems start with not knowing what you have. certforge-discovery scans your infrastructure for TLS certificates — public CT logs, live network endpoints, local filesystems, and Kubernetes secrets — and surfaces them in CertForge so you can track, govern, and renew them before they cause an outage.
| Source | What it finds |
|---|---|
| CT log | All certificates ever issued for your domains (via crt.sh) |
| TLS scan | Certificates live on network endpoints — hostnames, IPs, CIDR ranges |
| Local filesystem | Cert files on the host (/etc/ssl, nginx, apache, letsencrypt paths) |
| Kubernetes | All kubernetes.io/tls secrets across every namespace |
No CertForge account required for standalone scanning — use -domain, -target, and -out to scan and save results locally without any account. A CertForge account unlocks full governance workflows, expiry tracking, alerting, and the continuous agent mode.
Download the binary for your platform from the latest release:
# Linux (AMD64)
curl -Lo certforge-discovery https://github.com/CertForge-LLC/certforge-discovery/releases/latest/download/certforge-discovery-linux-amd64
chmod +x certforge-discovery
sudo mv certforge-discovery /usr/local/bin/Or install from source (requires Go 1.22+):
go install github.com/certforge-llc/certforge-discovery/cmd/certforge-discovery@latestScan any domain or network target and write results locally — no account needed:
# CT log scan → pretty table to stdout
certforge-discovery scan -domain example.com
# CT log + TLS live scan → CSV file
certforge-discovery scan -domain example.com -target 10.0.1.0/24 -out certs.csv
# Local filesystem scan → JSON file
certforge-discovery scan -local -out certs.json
# All sources → JSON
certforge-discovery scan -domain example.com -target 10.0.1.0/24 -local -k8s -out certs.json1. Run setup — picks your data region and connects to your CertForge account:
certforge-discovery setup2. Run a scan:
certforge-discovery scanResults appear immediately in CertForge → Discovery.
3. Run continuously (recommended — polls on the configured interval, default 6h):
certforge-discovery agent-config <path> Config file (default: ~/.certforge-discovery/config.yaml)
-domain <domain> Scan CT log for this domain (repeatable)
-target <host> TLS-scan this host, IP, or CIDR (repeatable)
-ports <ports> Ports for TLS scan (default: 443,8443)
-local Scan local filesystem for cert files
-k8s Scan Kubernetes TLS secrets
-out <file> Write to file (.csv or .json); stdout table if omitted
Setup writes a config file to ~/.certforge-discovery/config.yaml:
certforge_url: https://app.certgovernance.app # your region's URL
api_key: cf_... # from CertForge Settings → API Keys
poll_interval: 6h # how often agent re-scans
# Optional
scan_local: false # scan local filesystem for cert files
scan_k8s: false # scan Kubernetes TLS secrets
kubeconfig: "" # path to kubeconfig; empty = in-cluster config
storage_paths: # additional filesystem paths to scan
- /opt/app/certsEU West (GDPR) example:
certforge_url: https://eu.certgovernance.app
api_key: cf_...
poll_interval: 6h[Unit]
Description=CertForge Discovery Agent
After=network.target
[Service]
ExecStart=/usr/local/bin/certforge-discovery agent
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.targetsudo systemctl enable --now certforge-discoveryapiVersion: apps/v1
kind: Deployment
metadata:
name: certforge-discovery
namespace: certforge-system
spec:
replicas: 1
selector:
matchLabels:
app: certforge-discovery
template:
metadata:
labels:
app: certforge-discovery
spec:
serviceAccountName: certforge-discovery
containers:
- name: agent
image: ghcr.io/certforge-llc/certforge-discovery:latest
env:
- name: CERTFORGE_URL
value: https://app.certgovernance.app
- name: API_KEY
valueFrom:
secretKeyRef:
name: certforge-discovery-credentials
key: api_keyUse scan_k8s: true in your config (or set via environment variables) to enable Kubernetes secret scanning. The agent reads kubernetes.io/tls secrets across all namespaces — grant it a ClusterRole with secrets: [get, list].
If your network requires an outbound proxy, set the standard environment variables before running:
export HTTPS_PROXY=http://proxy.corp.com:8080
export NO_PROXY=localhost,127.0.0.1,10.0.0.0/8
certforge-discovery scan -domain example.comThis applies to CT log queries (crt.sh) and CertForge API calls. Live TLS scanning (-target) makes direct TCP connections and is not proxied — run the agent on a host that can reach the targets directly.
For a systemd service, set the proxy in the unit file:
[Service]
Environment=HTTPS_PROXY=http://proxy.corp.com:8080
Environment=NO_PROXY=localhost,10.0.0.0/8
ExecStart=/usr/local/bin/certforge-discovery agent -domain example.comcertforge-discovery sends certificate metadata only to your configured certforge_url. No certificate private keys are ever read or transmitted — the agent only reads the public certificate portion of TLS secrets and cert files.
Your data stays in the region you chose during setup. See CertForge data residency for details.
Apache 2.0