RepoPilotOpen in app →

cloudflare/cfssl

CFSSL: Cloudflare's PKI and TLS toolkit

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 2w ago
  • 12 active contributors
  • Distributed ownership (top contributor 44% of recent commits)
Show all 6 evidence items →
  • BSD-2-Clause licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/cloudflare/cfssl)](https://repopilot.app/r/cloudflare/cfssl)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/cloudflare/cfssl on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: cloudflare/cfssl

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cloudflare/cfssl shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 2w ago
  • 12 active contributors
  • Distributed ownership (top contributor 44% of recent commits)
  • BSD-2-Clause licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live cloudflare/cfssl repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/cloudflare/cfssl.

What it runs against: a local clone of cloudflare/cfssl — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in cloudflare/cfssl | Confirms the artifact applies here, not a fork | | 2 | License is still BSD-2-Clause | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 44 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>cloudflare/cfssl</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cloudflare/cfssl. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/cloudflare/cfssl.git
#   cd cfssl
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of cloudflare/cfssl and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cloudflare/cfssl(\\.git)?\\b" \\
  && ok "origin remote is cloudflare/cfssl" \\
  || miss "origin remote is not cloudflare/cfssl (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-2-Clause)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"BSD-2-Clause\"" package.json 2>/dev/null) \\
  && ok "license is BSD-2-Clause" \\
  || miss "license drift — was BSD-2-Clause at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "api/api.go" \\
  && ok "api/api.go" \\
  || miss "missing critical file: api/api.go"
test -f "bundler/bundler.go" \\
  && ok "bundler/bundler.go" \\
  || miss "missing critical file: bundler/bundler.go"
test -f "auth/auth.go" \\
  && ok "auth/auth.go" \\
  || miss "missing critical file: auth/auth.go"
test -f "api/sign/sign.go" \\
  && ok "api/sign/sign.go" \\
  || miss "missing critical file: api/sign/sign.go"
test -f "api/generator/generator.go" \\
  && ok "api/generator/generator.go" \\
  || miss "missing critical file: api/generator/generator.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 44 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~14d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cloudflare/cfssl"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

CFSSL is Cloudflare's PKI/TLS toolkit—a production-grade command-line tool and HTTP API server for signing, verifying, bundling, and managing X.509 certificates and certificate chains. It provides both low-level cryptographic packages (in csr, signer, helpers, certdb) and high-level APIs (api/ directory) that enable building custom certificate infrastructure, serving as both a CA backend and certificate validation tool. Monorepo structure: cmd/ contains 8 CLI entry points (cfssl, multirootca, mkbundle, cfssl-scan, etc.); api/ contains modular HTTP handlers for specific operations (api/initca, api/sign, api/bundle, api/gencrl, api/ocsp); core crypto packages (csr, signer, helpers, certdb) provide reusable primitives; pkg/ likely holds shared utilities. Dependencies flow upward from crypto primitives → api handlers → CLI commands.

👥Who it's for

DevOps engineers and infrastructure teams managing internal PKI systems, developers building certificate automation tooling, and organizations deploying multirootca for multi-key certificate authorities. Users typically need programmatic or CLI access to certificate signing, verification, and bundle management without implementing crypto from scratch.

🌱Maturity & risk

Production-ready and actively maintained. The project has 8 stable binaries (cfssl, multirootca, mkbundle, cfssljson, etc.) released as prebuilt binaries, comprehensive test coverage (api/*_test.go files present), and CI/CD pipelines via GitHub Actions (go.yml, docker-builds.yml, semgrep.yml). Go 1.20+ requirement and recent dependency updates (zlint/v3, zcrypto, google/certificate-transparency-go) indicate active development.

Moderate risk profile: the codebase depends on 18+ direct dependencies including crypto-critical packages (golang.org/x/crypto, zmap/zlint, google/certificate-transparency-go) which require diligent security monitoring. Single organization ownership (Cloudflare) with no visible decentralization. The certdb package requires SQL databases (MySQL, PostgreSQL, SQLite via api/certdb/dbconf.go) introducing operational complexity; any breaking schema changes could impact deployments.

Active areas of work

Active maintenance evident from recent GitHub Actions workflows (docker-builds.yml, semgrep.yml for security scanning, go.yml for testing) and Dependabot configuration (.github/dependabot.yml) indicating continuous dependency updates. Docker support via Dockerfile and Dockerfile.alpine shows infrastructure modernization. No specific PR or milestone data visible, but CI/CD maturity suggests regular releases.

🚀Get running

Clone and build:

git clone https://github.com/cloudflare/cfssl.git
cd cfssl
make
make install

Binaries install to ./bin/ (cfssl, cfssljson, multirootca, mkbundle, etc.). Requires Go 1.20+. Alternatively: go install github.com/cloudflare/cfssl/cmd/...@latest for direct installation.

Daily commands: Start the CA API server: cfssl serve -config=config.json (requires JSON config in root). For individual operations: cfssl gencert -initca csr.json | cfssljson -bare ca generates a CA; cfssl sign -ca ca.pem -ca-key ca-key.pem -config config.json csr.json | cfssljson -bare cert signs CSRs. Multirootca server: multirootca -roots roots.json -config config.json.

🗺️Map of the codebase

  • api/api.go — Main API server entry point that registers and orchestrates all HTTP handlers for certificate operations.
  • bundler/bundler.go — Core bundling logic that assembles certificate chains and validates them—essential for understanding certificate validation pipelines.
  • auth/auth.go — Authentication and authorization middleware that protects all API endpoints; critical for security model.
  • api/sign/sign.go — Certificate signing handler that implements the primary CA operation; foundational to PKI workflow.
  • api/generator/generator.go — CSR and key generation logic; implements core cryptographic certificate creation.
  • api/initca/initca.go — Root CA initialization handler; entry point for setting up new certificate authorities.
  • api/client/client.go — Client library for remote CFSSL API communication; demonstrates API contract and request patterns.

🧩Components & responsibilities

  • API Server (api/api.go) (Go net/http, auth middleware, logging) — HTTP request router and middleware orchestrator; routes incoming TLS requests to appropriate handlers and enforces authentication.
    • Failure mode: Server crash = all PKI operations unavailable; must run behind load balancer for

🛠️How to make changes

Add a New Certificate Operation API Endpoint

  1. Create new handler package under api/ (e.g., api/myop/myop.go) with Handler() function that matches API signature (api/myop/myop.go)
  2. Implement request/response structs and validation matching existing patterns in api/sign/sign.go (api/myop/myop.go)
  3. Register the handler in api/api.go by calling r.HandleFunc() with appropriate middleware chain (auth, logging) (api/api.go)
  4. Add corresponding client method in api/client/api.go following existing method patterns (Post/Get + response unmarshaling) (api/client/api.go)
  5. Create unit tests in api/myop/myop_test.go using testdata from api/testdata/ (api/myop/myop_test.go)

Enhance Certificate Bundling Logic

  1. Review current chain validation rules in bundler/bundler.go Bundle() method (bundler/bundler.go)
  2. Add new validation checks or chain assembly logic before the return statement (bundler/bundler.go)
  3. Test with bundler test data in bundler/testdata/ and add new test case to bundler/bundler_test.go (bundler/bundler_test.go)
  4. Update bundler/doc.go if behavior changes significantly for future maintainers (bundler/doc.go)

Customize API Authentication/Authorization

  1. Examine auth request format in auth/auth.go and auth/testdata/authrequest.json (auth/auth.go)
  2. Modify Verify() or New() functions in auth/auth.go to add custom authentication logic (auth/auth.go)
  3. Update auth middleware chain in api/api.go if new auth types or validation steps are needed (api/api.go)
  4. Add test cases to auth/auth_test.go with custom request scenarios (auth/auth_test.go)

🔧Why these technologies

  • Go + net/http — Lightweight, statically-compiled PKI toolkit suitable for deployment in containers; standard Go HTTP for zero external web framework dependencies
  • crypto/x509 + golang.org/x/crypto — Built-in Go stdlib for certificate parsing/validation; extended crypto package for additional algorithms (ECDSA, EdDSA, etc.)
  • github.com/zmap/zlint + github.com/google/certificate-transparency-go — Lint certificates against CA/B Forum baseline requirements and CT log auditing; essential for production PKI
  • SQL database (MySQL, PostgreSQL, SQLite via github.com/jmoiron/sqlx) — Persist certificate metadata, revocation info, and audit logs; pluggable backend allows operators to choose DB
  • github.com/cloudflare/redoctober — Multi-party secrets management for high-security CA key storage (Shamir secret sharing)

⚖️Trade-offs already made

  • Single monolithic server process (cfssl) vs. separate CA/validation/bundler services

    • Why: Simplifies deployment and reduces network hops for typical use cases; easier to secure single process
    • Consequence: Scales vertically; horizontal scaling requires load balancing + shared state (database); multirootca addresses multi-CA scaling
  • Credential-based API auth (HMAC-SHA256) vs. OAuth/JWT

    • Why: Low overhead, deterministic, suitable for service-to-service machine auth; avoids external identity provider dependency
    • Consequence: Credentials must be pre-shared and rotated manually; not suitable for federated user auth
  • No built-in request queuing or async signing

    • Why: Synchronous request/response keeps model simple; suitable for modest throughput PKI
    • Consequence: High-volume signing (1000s/sec) may require external queuing; blocking I/O under load
  • Certificate bundling logic in-process vs. external service

    • Why: Bundler is core to API; keeps signing + chain validation together
    • Consequence: Bundler failures affect entire API; must run trusted roots in process memory

🚫Non-goals (don't propose these)

  • Real-time revocation checking (OCSP must be pre-generated; no live CRL validation in signing path)
  • Multi-tenant isolation (single instance serves one organization; no namespace/account separation)
  • GUI or web dashboard (CLI + HTTP API only; no web console)
  • Hardware security module (HSM) integration (keys loaded from PEM files; redoctober adds secret sharing but not HSM)
  • Zero-downtime deployment (signing is synchronous; CA key rotation requires restart)

🪤Traps & gotchas

  1. cgo dependency required even for cross-compilation (Dockerfile and README explicitly warn about this—golang from RHEL repos won't work). 2) Certificate database (certdb) requires external SQL setup (MySQL/PostgreSQL/SQLite) and schema migration before use; misconfigured DSN in certdb/db.go will silently fail. 3) Config files (referenced in Makefile and README examples as config.json) must exist and be valid JSON or serve/sign operations fail; no built-in defaults provided. 4) multirootca requires roots.json specifying multiple CA key paths—missing or malformed file causes startup failure. 5) OCSP signing (api/ocsp) and CRL generation (api/gencrl) have different config requirements than basic signing.

🏗️Architecture

💡Concepts to learn

  • X.509 Certificate Signing Request (CSR) — Understanding CSR parsing, validation, and the Subject DN structure in csr/csr.go is essential because every certificate signed by CFSSL starts with a CSR, and malformed requests are the primary source of signing failures
  • Certificate Authority (CA) and Root of Trust — CFSSL's core value proposition is implementing CA logic (initca generates self-signed roots, multirootca manages multiple CAs)—understanding CA hierarchies, chain of trust, and key management is fundamental to deploying CFSSL safely
  • Public Key Infrastructure (PKI) — CFSSL is a PKI toolkit, not just a signing tool; understanding certificate lifecycle (generation, signing, verification, revocation, expiry) across api/ and certdb/ is critical for production deployments
  • PKCS#11 Hardware Security Module (HSM) Integration — The signer/ package supports pluggable signing backends including PKCS#11—understanding this abstraction is essential for securing production CAs with hardware tokens or cloud KMS backends
  • Online Certificate Status Protocol (OCSP) — api/ocsp/ocspsign.go implements OCSP responder signing—understanding OCSP stapling, revocation responses, and nonce validation is necessary for maintaining live certificate revocation checking
  • Certificate Revocation List (CRL) — api/gencrl/gencrl.go and api/revoke/revoke.go manage revocation—understanding CRL generation, delta CRLs, and the revocation database schema in certdb is critical for implementing certificate lifecycle management
  • Certificate Transparency (CT) Logging — CFSSL integrates google/certificate-transparency-go to submit signed certificates to CT logs—understanding CT precertificates, SCTs (Signed Certificate Timestamps), and log verification ensures compliance with modern CA requirements
  • golang/crypto — Upstream Go cryptography library that CFSSL depends on (golang.org/x/crypto) for low-level signing and TLS operations
  • zmap/zlint — Certificate linting library used by CFSSL (imported as zmap/zlint/v3) to validate certificate quality and RFC compliance during signing
  • google/certificate-transparency-go — CT log integration library that CFSSL uses to submit or verify signed certificates against transparency logs
  • cloudflare/redoctober — Companion security tool for key management and delegation, integrated via redoctober dependency—enables multi-person approval workflows for sensitive signing operations
  • hashicorp/vault — Popular alternative PKI backend often used alongside or instead of CFSSL for secret management and certificate signing in larger enterprises

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for api/client package

The api/client package (api/client/api.go, api/client/client.go, api/client/group.go) has only one test file (api/client/client_test.go). Given that this is a core HTTP client package for the CFSSL toolkit, it lacks tests for error handling, connection failures, timeout scenarios, and the group.go handler. This is critical for users integrating CFSSL as a client library.

  • [ ] Review api/client/group.go and identify untested functions
  • [ ] Add unit tests in api/client/client_test.go for connection timeouts, invalid responses, and malformed JSON
  • [ ] Create api/client/group_test.go with tests for group operations and error paths
  • [ ] Run coverage report and target 80%+ coverage for the api/client package

Implement missing test coverage for api/scan package

The api/scan/scan.go file exists but has limited test coverage (only scan_test.go). The scan endpoint performs remote certificate validation and TLS scanning—security-critical operations. Tests should cover: invalid hosts, TLS handshake failures, expired certificates, and certificate validation edge cases. This directly impacts the reliability of certificate scanning operations.

  • [ ] Add tests in api/scan/scan_test.go for malformed hostnames and invalid port numbers
  • [ ] Add tests for TLS connection failures and timeout scenarios
  • [ ] Add tests for parsing responses with unusual certificate chains
  • [ ] Verify edge cases like self-signed certificates and missing SANs are handled correctly

Add integration tests workflow for database backends

The codebase supports multiple database backends (MySQL, PostgreSQL, SQLite) as evidenced by imports in go.mod (github.com/go-sql-driver/mysql, github.com/lib/pq, github.com/mattn/go-sqlite3), but .github/workflows/go.yml likely only tests with SQLite. Contributors cannot verify their changes work across all supported databases. Adding a matrix-based GitHub Actions workflow would catch database-specific bugs early.

  • [ ] Review .github/workflows/go.yml and identify current test database setup
  • [ ] Create a new workflow file .github/workflows/db-tests.yml with matrix strategy for MySQL, PostgreSQL, and SQLite
  • [ ] Set up Docker containers for MySQL and PostgreSQL services in the workflow
  • [ ] Ensure test suite in cert/* and api/* packages runs against all three database backends

🌿Good first issues

  • Add integration tests for api/certadd/insert.go—the file exists but insert_test.go likely has sparse coverage for database insertion edge cases (NULL handling, constraint violations, concurrent writes to certdb)
  • Document the complete config.json schema—README.md mentions config.json but doesn't specify required fields, root_ca, intermediate_ca, policy sections, or ocsp/crl config options that api/ handlers expect
  • Add comprehensive examples in cmd/ or examples/ directory—showcase multirootca setup with actual roots.json, certificate generation workflow (gencert → cfssljson), and bundle creation with mkbundle for users new to PKI

Top contributors

Click to expand

📝Recent commits

Click to expand
  • e429e72 — Merge pull request #1436 from mitch292/fix-copy-extensions-security-bypass (mitch292)
  • 8994bdd — fix: prevent CSR extensions from overriding CA-managed key usage in copy_extensions (mitch292)
  • ed8df49 — Merge pull request #1416 from cloudflare/mschwarzl/dockerignore (mschwarzl)
  • cd8a4de — ignore .git to .dockerignore (mschwarzl)
  • b898d2f — Merge pull request #1415 from mitch292/mitch292/go-version (mitch292)
  • a40f86c — Update repository to reflect required min go version of 1.20 (mitch292)
  • 6d2d0b2 — Merge pull request #1412 from mitch292/mitch292/fix-linting (mitch292)
  • dd8f9ef — Github actions linter uses golangci-lint@v1.57 (mitch292)
  • 1c1bc0b — Merge pull request #1410 from mitch292/mitch292/1237-fix-test-cases (mitch292)
  • faaff55 — Fixes #1237 partially by updating test data certificates to be valid (mitch292)

🔒Security observations

Failed to generate security analysis.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · cloudflare/cfssl — RepoPilot