Skip to main content
certforge-discovery is an open-source agent that scans your infrastructure for TLS certificates and surfaces them in CertForge. It finds certificates you didn’t know you had — shadow certs from acquisitions, forgotten wildcards, certs issued by shadow IT — before they expire undetected. GitHub: CertForge-LLC/certforge-discovery

What it scans

Installation

Download the binary for your platform from the latest release:
Verify the download:
Or build from source (requires Go 1.22+):

Quick start — no account required

Run a scan locally without a CertForge account. Results print to stdout or write to a file:
Use -dry-run with any scan to print the exact JSON payload that would be sent to CertForge — without posting anything:

Connect to CertForge

The discovery agent supports two connection methods. mTLS enrollment is recommended — it connects directly to the CertForge agent endpoint on port 8443, bypassing Cloudflare, and uses a pinned mutual-TLS certificate rather than a long-lived API key. Generate an enrollment token in CertForge:
  1. Go to Integrations → Connector Agents
  2. Click + Enroll Agent and choose type Discovery
  3. Give it a label (e.g. prod-scanner)
  4. Copy the one-time token
Run the enroll command on the agent host:
The enroll command writes your mTLS credentials and updates ~/.certforge-discovery/config.yaml automatically. The config will contain:
When mtls_host / mtls_cert are set, api_key is ignored. Traffic goes directly to port 8443 on the CertForge agent endpoint.
Then run a scan:

Option B — API key setup (legacy)

Run setup to pick your data region and connect with an API key:
This writes a config file to ~/.certforge-discovery/config.yaml:
Then run a scan:

Discovered certificates appear in CertForge under Discovery with source: ct_log, tls_scan, local, or k8s. They are automatically evaluated against your Domain Trust Profiles and flagged for policy mismatches.

Continuous agent mode

Run the agent continuously so CertForge always has a current picture of your cert inventory:
The agent re-scans on the poll_interval set in its config (default 6 hours).

Configuration

~/.certforge-discovery/config.yaml — written by enroll (mTLS) or setup (API key):
EU West (GDPR) — API key auth:
EU West (GDPR) — mTLS auth:

Private CA awareness

If your environment uses certforge-connector with a private_ca: configured, point known_internal_cas at the same CA cert file. Discovery will then:
  1. Cryptographically verify (TLS scan, local filesystem, Kubernetes) or name-match (CT log) each discovered cert against the CA
  2. Tag matching certs as issuer_type: internal_ca in CertForge
  3. Show them distinctly in the Discovery view so your team can govern internal issuance separately from public CA certs
This is a read-only classification — discovery never contacts the CA or generates certificates.

Scan flags

Running as a service

systemd:
Kubernetes (mTLS — recommended): Store the mTLS credentials from certforge-discovery enroll in a Secret:
Kubernetes (API key — legacy):
Grant the service account secrets: [get, list] cluster-wide so the agent can read kubernetes.io/tls secrets across all namespaces.

What is sent to CertForge

The agent posts certificate metadata only — no private keys, no plaintext traffic, no filesystem contents beyond recognized cert formats. For Kubernetes secrets: only the tls.crt field is read — tls.key is never accessed or transmitted.

Corporate proxy

Live TLS scanning (-target) makes direct TCP connections and is not proxied — run the agent on a host with direct access to the targets.

What happens after discovery

Discovered certs land in CertForge with governance_status = untracked. Your team can:
  • Track — acknowledge the cert; CertForge monitors it for expiry and includes it in compliance reports
  • Dismiss — mark as a known false positive; excluded from open issues
  • Leave as untracked; it contributes to the Ungoverned KPI on the Dashboard
See Certificate Discovery for the full governance workflow.