certificate-validate

module
v1.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: Apache-2.0

README

Certificate Validate

A modern, extensible SSL/TLS certificate validation tool written in Go. Fetches and inspects certificate information from remote hosts via CLI or HTTP API.

For AI agents: this README is the human-facing usage/feature reference. Project working conventions (English, SOLID, coverage, lefthook, invariants) live in AGENTS.md, which is the canonical instruction file for AI coding agents.

Features

  • CLI Mode — Check certificates with output formats (JSON/table), watch mode, filtering
  • HTTP API — RESTful API with Swagger UI, rate limiting, optional API key auth
  • Export — Export certificate data to JSON or CSV via CLI or API
  • Watch Mode — Continuous checking with configurable interval
  • Alert Webhook — POST alerts when certificates approach expiration
  • History — Records check results in JSONL with automatic rotation
  • Prometheus Metrics — Exposes certificate_days_left and certificate_expired gauges
  • Revocation Checks — OCSP + CRL validation per certificate
  • Kubernetes monitoring — k8s monitor scans TLS Secrets + Ingresses, exports Prometheus metrics with K8s labels, fires webhook alerts, and can auto-renew expiring certs via cert-manager (read-only by default, opt-in renewal; see docs/K8S_INTEGRATION.md)
  • Hot-Reload — SIGHUP reloads config without restarting the server
  • Self-Signed CAs — Global and per-host trusted CA certificates
  • Environment Variables — CV_ prefix overrides for all config fields
  • Concurrent Processing — Parallel certificate fetching with semaphore
  • Minimal Dependencies — Small Docker image (~10MB)
  • Extensible Architecture — SOLID principles with clean interfaces

Quick Start

# From source
go install github.com/fabianoflorentino/certificate-validate/cmd/certificate-validate@latest

# Build locally
git clone https://github.com/fabianoflorentino/certificate-validate.git
cd certificate-validate
go build -o certificate-validate ./cmd/certificate-validate

# Docker
docker build -t certificate-validate .

# Run CLI check
./certificate-validate check

# Run API server
./certificate-validate serve

Documentation

Resource Description
docs/ARCHITECTURE.md Architecture overview with 13 Mermaid flowcharts
docs/K8S_INTEGRATION.md Kubernetes integration roadmap + Phases 1–2 k8s monitor implementation
dev/README.md Disposable Kubernetes dev environment (kind + cert-manager)
Swagger UI Interactive API docs at http://localhost:5000/swagger/ (when server is running)
docs/swagger.yaml OpenAPI 3.0 specification

Architecture

certificate-validate/
├── cmd/certificate-validate/
│   └── main.go                    # Entry point
├── config/
│   └── settings.yml               # YAML configuration
├── docs/
│   ├── ARCHITECTURE.md            # Architecture & flowcharts
│   └── swagger.yaml               # OpenAPI 3.0 spec
├── internal/
│   ├── api/                       # HTTP handlers + middleware + rate limiter
│   │   ├── api.go                 # Routes, handlers, auth, rate limiting
│   │   └── static/                # Embedded frontend + Swagger UI
│   ├── certificate/               # Domain: Certificate value object
│   │   ├── certificate.go         # FromX509, TLSVersionString, BuildChain
│   │   └── errors.go              # Domain-specific errors
│   ├── checker/                   # Use case: orchestration
│   │   └── checker.go             # Checker (Fetcher + Formatter)
│   ├── cmd/                       # CLI (Cobra)
│   │   ├── root.go                # Root + completion + global flags
│   │   ├── check.go               # Check certificates
│   │   ├── serve.go               # HTTP API server
│   │   ├── export.go              # Export JSON/CSV
│   │   ├── k8s.go                 # `k8s monitor` (Kubernetes agent)
│   │   └── version.go             # Version info
│   ├── config/                    # YAML loader + env var overrides
│   │   └── config.go              # Load, Validate, applyEnvOverrides
│   ├── fetcher/                   # TLS fetcher with CA support
│   │   └── fetcher.go             # Fetcher + per-host CAs
│   ├── formatter/                 # Output formatters
│   │   └── formatter.go           # FormatTable, FormatJSON, FormatCSV
│   ├── history/                   # JSONL history recorder
│   │   └── history.go             # Record, rotate, query
│   ├── k8smonitor/                # Kubernetes certificate monitoring (Phases 1–2)
│   │   ├── client.go              # client-go setup + discovery (Secrets/Ingresses)
│   │   ├── analyzer.go            # Bundle parse + chain/OCSP/CRL analysis
│   │   ├── monitor.go             # Scan orchestration (single scan + watch)
│   │   ├── renewer.go             # Auto-renewal (annotate → wait → validate)
│   │   ├── model.go               # K8sCertificate model
│   │   ├── metrics.go             # Dedicated Prometheus registry + gauges
│   │   └── webhook.go             # Rate-limited alert webhook
│   ├── metrics/                   # Prometheus exposition
│   │   └── metrics.go             # Gauges + /metrics handler
│   ├── notifier/                  # Webhook alerts
│   │   └── notifier.go            # Periodic alert checks
│   ├── revocation/                # OCSP + CRL checks
│   │   └── revocation.go          # CheckOCSP, CheckCRL
│   └── service/                   # Facade layer
│       └── service.go             # CertService
├── kubernetes/
│   └── monitor/                   # K8s monitor deployment (rbac, daemonset, service, servicemonitor)
├── scripts/                       # Dev environment helper scripts (setup-cluster, teardown, monitor-logs)
├── dev/
│   └── README.md                  # Disposable Kubernetes dev environment guide
├── Dockerfile                     # Multi-stage: `production` (default) + `dev`
├── docker-compose.yml             # Services: certificate-validate (app) + dev (profile)
├── Makefile
└── README.md

Configuration

Create a config/settings.yml file:

check_time: 30                    # Interval for watch/history/metrics (seconds)
api_key: "sk-1234"                # API key for X-API-Key auth (optional)

app_configs:
  - name: 'certificate-validate'
    host: '0.0.0.0'
    port: '5000'
    environment: 'production'
    debug: false

hosts:
  - name: "GitHub"
    url: 'github.com'
    port: '443'
    # ports: [443, 8443]          # Multiple ports per host (optional)
    # timeout: 10                  # Per-host dial timeout (seconds)
    # trusted_cas:                 # Per-host trusted CAs
    #   - '/certs/internal-ca.pem'

prometheus:
  enabled: false                   # Enable Prometheus metrics at /metrics
  # address: ':9090'

webhook:
  # url: 'https://hooks.example.com/alert'
  threshold: 15                    # Alert when days left drops below this
  interval: 1800                   # Check interval (seconds)

history:
  enabled: true                    # Record check history to JSONL
  file_path: "data/history.jsonl"
  max_entries: 10000               # Rotate after this many entries
  max_days: 90                     # Remove entries older than this

trusted_cas:
  # - '/etc/certificates/my-ca.pem'
Environment Variables

All config fields can be overridden via environment variables with the CV_ prefix:

Variable Overrides
CV_CHECK_TIME check_time
CV_API_KEY api_key
CV_APP_HOST app_configs[0].host
CV_APP_PORT app_configs[0].port
CV_PROMETHEUS_ENABLED prometheus.enabled
CV_PROMETHEUS_ADDRESS prometheus.address
CV_WEBHOOK_URL webhook.url
CV_WEBHOOK_THRESHOLD webhook.threshold
CV_WEBHOOK_INTERVAL webhook.interval
CV_HISTORY_ENABLED history.enabled
CV_HISTORY_FILE_PATH history.file_path
CV_HISTORY_MAX_ENTRIES history.max_entries
CV_HISTORY_MAX_DAYS history.max_days
CV_TRUSTED_CAS trusted_cas (comma-separated)

Example:

CV_API_KEY="sk-secret" CV_WEBHOOK_URL="https://hooks.example.com/alert" ./certificate-validate serve

CLI Usage

Global Flags
Flag Description
-c, --config Path to config file (default: config/settings.yml)
--log-file Write structured logs to file (also written to stderr)
certificate-validate check

Check certificates from configured hosts or a single host.

./certificate-validate check                          # All hosts from config
./certificate-validate check -o table                 # Table output
./certificate-validate check --host github.com        # Single host, no config
./certificate-validate check --host github.com --port 8443
./certificate-validate check --min-days 30            # Only show certs ≤30 days
./certificate-validate check --watch                  # Continuous checking
Flag Description
-w, --watch Continuously check at the configured interval
-o, --output Output format: json (default) or table
--host Check a single host directly (no config needed)
--port Port for --host (default: 443)
--min-days Only show certificates with ≤ this many days remaining
certificate-validate serve

Start the HTTP API server.

./certificate-validate serve                                    # HTTP on :5000
./certificate-validate serve --tls-cert cert.pem --tls-key key.pem  # HTTPS
./certificate-validate serve --api-key "sk-1234"                # Require API key
Flag Description
--tls-cert Path to TLS certificate file
--tls-key Path to TLS private key file
--api-key API key (overrides config/api_key)

Send SIGHUP to reload configuration without restarting:

kill -HUP <pid>
certificate-validate export

Export certificate data to JSON or CSV.

./certificate-validate export                            # JSON to stdout
./certificate-validate export -f csv                     # CSV to stdout
./certificate-validate export -f json -o data/certs.json # Write to file
Flag Description
-f, --format Output format: json (default) or csv
-o, --output-file Write to file instead of stdout
certificate-validate k8s monitor

Monitor TLS certificates in a Kubernetes cluster (Phases 1–2 of the Kubernetes integration). Discovers TLS Secrets and Ingresses, analyzes each certificate, exports Prometheus metrics, and optionally fires webhook alerts. By default it is read-only (no cluster writes); set --renew-threshold to enable Phase 2 auto-renewal of expiring certificates via cert-manager.

# Single scan, print each certificate as JSON
./certificate-validate k8s monitor

# Watch mode: scan every 5 minutes, serve metrics on :9102, alert on webhook
./certificate-validate k8s monitor \
  --watch-interval=300 \
  --metrics-addr=:9102 \
  --webhook-url https://hooks.example.com/alert \
  --check-revocation

# Restrict to specific namespaces
./certificate-validate k8s monitor -n cert-manager -n default

# Auto-renew certificates at or below 15 days left (via cert-manager)
./certificate-validate k8s monitor --watch-interval=300 --renew-threshold=15
Flag Default Description
-n, --namespace all Namespaces to scan (repeatable / comma-separated)
--kubeconfig in-cluster / ~/.kube/config Path to kubeconfig
--check-revocation false Perform OCSP/CRL revocation checks
--watch-interval 0 (single scan) Repeat scan every N seconds
--webhook-url empty URL to POST expiring-cert alerts
--webhook-threshold 15 Alert when days-left is at/below this value
--webhook-interval 300 Min seconds between alerts per resource
--renew-threshold 0 (disabled) Auto-renew certs at/below this many days left
--renew-timeout 120 Max seconds to wait for cert-manager to re-issue
--metrics-addr empty Serve Prometheus metrics on this address (e.g. :9102)

Deployment manifests (DaemonSet, RBAC, Service, ServiceMonitor) live in kubernetes/monitor/. Test locally with the disposable dev environment (make dev/up … make dev/setup, see dev/README.md).

certificate-validate version

Print build information.

$ ./certificate-validate version
certificate-validate v1.0.0
  commit:     abc1234
  built:      2026-07-02T00:00:00Z
  go:         go1.24 linux/amd64
certificate-validate completion

Generate shell completion scripts.

source <(./certificate-validate completion bash)
source <(./certificate-validate completion zsh)
./certificate-validate completion fish | source

API

The API server is available at http://localhost:5000. Interactive docs at http://localhost:5000/swagger/.

API Key Authentication

When api_key is configured (via config file, --api-key flag, or CV_API_KEY env var), all routes except /health require the X-API-Key header:

curl -H "X-API-Key: sk-1234" http://localhost:5000/api/v1/cert/info/all
Rate Limiting

All requests (except static files) are rate-limited via a token bucket: 100 req/s, burst 200. Exceeded requests receive 429 Too Many Requests with a Retry-After: 1 header.

Endpoints
Method Route Description
GET / Dashboard (embedded frontend)
GET /swagger/ Swagger UI (interactive API docs)
GET /swagger.yaml OpenAPI 3.0 specification
GET /health Health check (pings all hosts)
GET /api/v1/cert/info/all All certificates from configured hosts
GET /api/v1/cert/info/{hostname} Certificate for a specific host
GET /api/v1/cert/info/commonName Map of hostname → Common Name
GET /api/v1/cert/info/subjectAltName Map of hostname → SANs
GET /api/v1/cert/export/json Download all certificates as JSON file
GET /api/v1/cert/export/csv Download all certificates as CSV file
GET /api/v1/cert/history/{hostname} History of checks for a host
GET /metrics Prometheus metrics (if prometheus.enabled)
Example Response
{
  "commonName": "github.com",
  "subjectAltName": ["github.com", "www.github.com"],
  "issuer": "Sectigo Public Server Authentication CA DV E36",
  "type": "Domain Validation (DV) Web Server SSL Digital Certificate",
  "notBefore": "2024-01-01 00:00:00",
  "notAfter": "2025-01-01 23:59:59",
  "daysLeft": 365,
  "crl": ["http://crl.example.com/ca.crl"],
  "ocsp": ["http://ocsp.example.com"],
  "revocationStatus": "unknown",
  "hostname": "github.com",
  "port": 443,
  "tlsVersion": "TLS 1.3",
  "cipherSuite": "TLS_AES_128_GCM_SHA256",
  "chain": [
    {
      "subject": "CN=github.com,O=GitHub\\, Inc.,L=San Francisco,ST=California,C=US",
      "issuer": "CN=Sectigo Public Server Authentication CA DV E36",
      "notAfter": "2025-01-01 23:59:59",
      "fingerprint": "a1b2c3d4e5f6..."
    }
  ]
}

Docker

CLI Mode
docker run -v $(pwd)/config:/app/config certificate-validate check
docker run -v $(pwd)/config:/app/config certificate-validate check --watch
API Mode
docker run -p 5000:5000 -v $(pwd)/config:/app/config certificate-validate serve
Docker Compose
docker-compose up -d
curl http://localhost:5000/api/v1/cert/info/all
curl http://localhost:5000/swagger/

Self-Signed Certificate Monitoring

Add CA certificates to trusted_cas for servers using self-signed or privately-signed certificates:

trusted_cas:
  - '/etc/certificates/my-ca.pem'

Per-host CAs are also supported:

hosts:
  - name: "Internal"
    url: 'internal.example.com'
    port: '443'
    trusted_cas:
      - '/etc/certificates/internal-ca.pem'

Supported modes:

  • check and check --watch — uses configured CAs
  • serve — uses CAs for all certificate fetches

Development

make test               # Run all tests with race detector
make test/short         # Fast tests (no race)
make test/cover         # Coverage HTML report
make test/verbose       # Verbose output
make lint               # golangci-lint + go vet
make fmt                # gofmt all source
make build              # Build binary
make run                # Build and run
make run ARGS="check"   # Build and run with args
make tidy               # Tidy and verify modules
make clean              # Remove artifacts
Make Targets
make docker/build        # Build Docker image
make docker/run          # Build and run CLI in container
make docker/run/serve    # Build and run API server in container
make compose/up          # Start Docker Compose
make compose/down        # Stop Docker Compose
make compose/logs        # Follow logs

# Disposable Kubernetes dev environment (kind + cert-manager)
make dev/up              # Build + start the disposable dev container
make dev/shell           # Open a shell in the dev container
make dev/setup           # Create kind cluster + cert-manager + deploy monitor
make dev/scan            # One-off `k8s monitor` scan via the DaemonSet
make dev/logs            # Stream the deployed monitor logs
make dev/down            # Stop the dev container
make dev/destroy         # Remove container + cluster state (zero residue)

Contributing

This project follows specific conventions to maintain code quality and consistency:

  • Language: All code, comments, commits, and documentation must be in English
  • Architecture: Follow SOLID principles lightly — focused responsibilities, dependency injection, clean interfaces
  • Testing: Maintain ≥80% test coverage; never add production code without tests
  • Validation: All changes must pass lefthook hooks (pre-commit: lint + vet; pre-push: full test suite + coverage gate)
  • Commits: Small, thematic, English commits following conventional format

For complete working conventions, invariants, and toolchain notes, see AGENTS.md.

License

Apache License 2.0 — see LICENSE file for details.

Author

Fabiano Florentino

Directories

Path Synopsis
cmd
internal
api
Package api provides the HTTP API server for certificate validation.
Package api provides the HTTP API server for certificate validation.
certificate
Package certificate provides types and utilities for parsing, analyzing, and representing SSL/TLS certificate information.
Package certificate provides types and utilities for parsing, analyzing, and representing SSL/TLS certificate information.
checker
Package checker provides certificate checking orchestration with concurrent fetching and formatting capabilities.
Package checker provides certificate checking orchestration with concurrent fetching and formatting capabilities.
cmd
Package cmd provides the command-line interface for certificate-validate.
Package cmd provides the command-line interface for certificate-validate.
config
Package config provides application configuration loading and management.
Package config provides application configuration loading and management.
fetcher
Package fetcher provides TLS certificate fetching from remote hosts.
Package fetcher provides TLS certificate fetching from remote hosts.
formatter
Package formatter provides output formatting for certificate information.
Package formatter provides output formatting for certificate information.
history
Package history provides certificate check history recording and querying.
Package history provides certificate check history recording and querying.
k8smonitor
Package k8smonitor implements Kubernetes certificate monitoring, analyzing TLS certificates stored in Secrets and Ingresses, and optionally auto-renewing expiring certificates via cert-manager.
Package k8smonitor implements Kubernetes certificate monitoring, analyzing TLS certificates stored in Secrets and Ingresses, and optionally auto-renewing expiring certificates via cert-manager.
metrics
Package metrics provides Prometheus metrics exposition for certificate validation results.
Package metrics provides Prometheus metrics exposition for certificate validation results.
notifier
Package notifier provides webhook-based alert notifications for expiring certificates.
Package notifier provides webhook-based alert notifications for expiring certificates.
revocation
Package revocation provides OCSP and CRL checking for certificate revocation verification.
Package revocation provides OCSP and CRL checking for certificate revocation verification.
service
Package service provides the application's business logic layer, orchestrating certificate checking, history recording, and metrics updates.
Package service provides the application's business logic layer, orchestrating certificate checking, history recording, and metrics updates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL