Files
certctl/docs/reference/cli.md
T
shankar0123 b452013dd9 docs: Phase 5 — testing-guide.md prune (8268 → 0 lines, content dispersed)
Per Phase 1 audit at cowork/docs-overhaul-phase-1-audit-2026-05-04/
and the section-by-section plan in testing-guide-tumor.md.

testing-guide.md was 30% of all docs/ content (8268 lines) but was
integration test code written in markdown, not operator documentation.
The audit's tumor analysis disposed of every Part:
  - ~65% DELETE (test cases that already exist in code)
  - ~22% MOVE to inline test code
  - ~8% KEEP-COMPRESSED into focused operator-runbook docs
  - Title + contents + release sign-off ~5% KEEP

This commit ships the KEEP-COMPRESSED dispersal:

  docs/contributor/qa-prerequisites.md (NEW, ~120 lines):
    From testing-guide.md "Prerequisites" section. Stack boot procedure,
    demo data baseline, reference IDs operators reuse across QA docs.

  docs/contributor/gui-qa-checklist.md (NEW, ~105 lines):
    From testing-guide.md "Part 35: GUI Testing". Manual GUI verification
    pass for release sign-off. 25-row table covering every dashboard page.

  docs/contributor/release-sign-off.md (NEW, ~130 lines):
    From testing-guide.md "Release Sign-Off" section (originally 1009
    lines of per-test detail tables). Compressed to a release-day
    checklist organized by gate category: code state, automated gates,
    manual QA passes, release artefact verification, branch protection,
    post-release.

  docs/operator/performance-baselines.md (NEW, ~100 lines):
    From testing-guide.md "Part 39: Performance Spot Checks". Four
    operator-runnable benchmarks (API request handling, inventory list
    pagination, scheduler tick, bulk revoke) with baseline numbers and
    when-to-re-baseline guidance.

  docs/operator/helm-deployment.md (NEW, ~120 lines):
    From testing-guide.md "Part 52: Helm Chart Deployment". Operator
    runbook for the bundled deploy/helm/certctl/ chart: prereqs,
    install, four cert-source patterns, verify, upgrade, troubleshooting.

  docs/reference/cli.md (NEW, ~120 lines):
    From testing-guide.md "Part 28: CLI Tool". certctl-cli command
    reference with command-group breakdown, common workflows
    (list/filter, renew, revoke, bulk import, EST enrollment, status),
    output formats, CI/CD integration patterns.

docs/README.md navigation index updated to include the 6 new docs:
  Reference section gains: cli.md, release-verification.md (was added
    in Phase 13)
  Operator section gains: helm-deployment.md, performance-baselines.md
  Contributor section gains: qa-prerequisites.md, gui-qa-checklist.md,
    release-sign-off.md

docs/testing-guide.md deleted. Git history preserves the 8268 lines —
if any specific test case is found missing from inline test code or
the destination docs during future work, lift from `git show
HEAD~1:docs/testing-guide.md`.

Net: docs/ total line count drops by ~7700 lines (28%), from 26,369
to 18,742. testing-guide.md was the single largest doc; pruning it is
the single biggest content-edit win of the entire restructure.

Phase 5 is the last major content phase. Remaining: Phase 4 follow-on
(per-connector page extractions from reference/connectors/index.md),
Phase 15 (WHAT/HOW/WHY remediation), Phase 16 (final acceptance gate).
2026-05-05 03:38:54 +00:00

4.3 KiB

certctl CLI

Last reviewed: 2026-05-05

certctl-cli is the command-line interface to certctl. It wraps the REST API as terminal commands so operators and CI/CD pipelines can drive certctl without writing curl invocations.

Install

go install github.com/certctl-io/certctl/cmd/cli@latest

The binary lands at $GOBIN/cli (or $HOME/go/bin/cli if GOBIN is unset). Rename to certctl-cli if you prefer.

Configure

The CLI reads three environment variables:

export CERTCTL_SERVER_URL=https://localhost:8443
export CERTCTL_API_KEY=your-api-key
export CERTCTL_SERVER_CA_BUNDLE_PATH=/path/to/ca.crt

Or pass them per-invocation:

certctl-cli --server https://localhost:8443 --api-key your-key --ca-bundle ca.crt certs list

For local development against a self-signed bootstrap cert, --insecure skips TLS verification. Never set this in production.

Command groups

The CLI is organized by resource:

certctl-cli certs    [list|get|renew|revoke]
certctl-cli agents   [list|get]
certctl-cli jobs     [list|get|cancel]
certctl-cli import   [bulk PEM import]
certctl-cli est      [enroll|reenroll]
certctl-cli status   [server health + summary stats]
certctl-cli version  [CLI + server version]

Common workflows

List + filter certificates

# All certs
certctl-cli certs list

# Filter by environment
certctl-cli certs list --env production

# JSON output (default is table)
certctl-cli certs list --format json

# Sort + paginate
certctl-cli certs list --sort -expires_at --limit 50

# Time-range filter (RFC 3339)
certctl-cli certs list --expires-before 2026-06-01T00:00:00Z

# Sparse fields — only return the columns you need
certctl-cli certs list --fields id,common_name,expires_at,status

Trigger renewal

certctl-cli certs renew mc-api-prod
# Returns the job id; track with: certctl-cli jobs get <job-id>

Revoke

# Single revoke
certctl-cli certs revoke mc-api-prod --reason keyCompromise

# Bulk revoke by filter
certctl-cli certs revoke --profile prof-deprecated --reason superseded
certctl-cli certs revoke --team t-payments --reason cessationOfOperation
certctl-cli certs revoke --issuer iss-old-vault --reason cACompromise

Reason codes are the canonical RFC 5280 §5.3.1 set: unspecified, keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, removeFromCRL, privilegeWithdrawn, aACompromise. Anything else returns an error.

Bulk import

# Import a directory of PEMs
certctl-cli import /etc/letsencrypt/live/

# Import a single concatenated bundle
certctl-cli import certs.pem

Each cert lands in the inventory as Unmanaged (per the discovery model). Triage from the dashboard or via certctl-cli certs claim <id> once you've decided to actively manage it.

EST enrollment

# Enroll a new device cert via EST simpleenroll
certctl-cli est enroll --csr device.csr --output device.crt

# Re-enroll (renew) an existing device cert
certctl-cli est reenroll --csr device.csr --client-cert device.crt --client-key device.key

Server status

certctl-cli status
# Health: ok
# Total certificates: 145
# Expiring (30d): 12
# Active jobs: 3
# Pending renewals: 8

Output formats

  • --format table (default) — human-readable terminal output
  • --format json — JSON for piping into jq, scripts, dashboards

The CLI is built with Go's standard library only — no external dependencies. The binary is small (~10MB) and statically linked.

Wiring into CI/CD

Common pattern: a CI step that issues a cert from your internal CA, deploys it via certctl, and verifies the deploy:

certctl-cli certs renew mc-api-prod --wait
certctl-cli jobs get $(certctl-cli certs renew mc-api-prod --json | jq -r '.job_id') --wait
certctl-cli certs get mc-api-prod --json | jq -r '.expires_at'

The --wait flag blocks until the job reaches a terminal state (Completed / Failed / Cancelled), which is what CI scripts actually need.