Lab CA

This repository contains a simple CLI tool for managing a Certificate Authority (CA).

It is designed to be easy to use and provides a basic set of CA features:

  • Create a CA and a self-signed CA certificate
  • Create and sign common types of certificates:
    • Server certificate
    • Client certificate
    • Code signing certificate
    • Email certificate
  • Revoke a certificate
  • List issued certificates
  • Create a CRL (Certificate Revocation List)

NOTE: Certificate types can be combined (e.g. server,client).

Usage

The tool is used from the command line. It has a simple command structure:

lab-ca <command> [options]

The main commands available are:

  • initca — Initialize a new CA and create a self-signed CA certificate and key.
  • issue — Issue a new certificate signed by the CA (single certificate, command-line options).
  • provision — Provision multiple certificates from a batch file (HCL) in one go.
  • revoke — Revoke a certificate by name or serial number.
  • crl — Generate a Certificate Revocation List (CRL) from revoked certificates.
  • list — List issued certificates (optionally including revoked).
  • version — Show version information for the tool.

Run the command with -h or --help or without any arguments to see usage information. Each command has its own set of options, arguments, and a help message.


CA Initialization

Create a new CA configuration file (HCL):

ca "example_ca" {
  name = "Example CA"
  country = "US"
  organization = "ACME Corp"
  key_size = 4096
  validity = "10y"

  paths {
    certificates = "certs"
    private_keys = "private"
    state_file   = "ca_state.json"
  }
}
  • The ca block's label is used as a logical name for the CA and for the default state file name.
  • The paths block defines where certificates, private keys, and the CA state file are stored.
  • On Linux/macOS, the private keys directory is created with 0700 permissions.
  • The command does not encrypt private keys. Do not use in production.

Listing Certificates

List all issued (non-revoked) certificates:

lab-ca list

To include revoked certificates:

lab-ca list --revoked

Issuing a Certificate

Issue a new certificate from the command line:

lab-ca issue --name <name> [--subject <subject>] [--type <type>] [--validity <period>] [--san <SAN> ...] [--dry-run] [--verbose]
  • --name (required): Name for the certificate and key files (used as subject if --subject is omitted)
  • --subject: Subject Common Name or full DN (optional, defaults to --name)
  • --type: Certificate type: client, server, code-signing, email (comma-separated for multiple usages; default: server)
  • --validity: Validity period (e.g. 2y, 6m, 30d; default: 1y)
  • --san: Subject Alternative Name (repeatable; e.g. dns:example.com, ip:1.2.3.4, email:user@example.com)
  • --dry-run: Validate and show what would be created, but do not write files
  • --verbose: Print detailed information

Provisioning Certificates (Batch)

Provision multiple certificates from a batch file (HCL):

lab-ca provision --file <certificates.hcl> [--verbose]

Example HCL Provisioning File

defaults {
    subject = "{{ .Name }}.example.org"
    type = "server,client"
    validity = "1y"
    san = ["DNS:{{ .Name }}.example.org"]
}

variables = {
    Domain = "example.net"
    Country = "EX"
}

certificate "service1" {
    # from default: subject = "{{ .Name }}.example.org"
    # from default: type = "server,client"
    # from default: validity = "1y"
    # from default: san = ["DNS:service1.example.org"]
}

certificate "service2" {
    subject = "{{ .Name }}.{{ .Domain }}" # result: service2.example.net
    san = ["DNS:{{ .Name }}.{{ .Domain }}"] # result: [ "DNS:service2.example.net" ]
}

certificate "service3" {}

certificate "user1" {
    subject = "CN=User One,emailAddress=user1@example.org,O=Example,C=US"
    type = "client,email"
    validity = "1y"
    san = ["email:user1@example.net"]
}
  • The defaults block provides default values for all certificates unless overridden.
  • The variables map can be used in Go template expressions in any field.
  • Each certificate block defines a certificate to be issued. The block label is available as {{ .Name }} in templates.
  • Fields:
    • subject: Subject string (can be a template)
    • type: Comma-separated usages (server, client, code-signing, email)
    • validity: Validity period (e.g. 1y, 6m, 30d)
    • san: List of SANs (e.g. DNS:..., IP:..., email:...)

Revoking a Certificate

Revoke a certificate by name or serial number:

lab-ca revoke --name <name> [--reason <reason>]
lab-ca revoke --serial <serial> [--reason <reason>]
  • --reason can be one of: unspecified, keyCompromise, caCompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, removeFromCRL (default: cessationOfOperation)

Generating a CRL

Generate a Certificate Revocation List (CRL) from revoked certificates:

lab-ca crl [--crl-file <path>] [--validity-days <days>]
  • --crl-file: Output path for CRL file (default: crl.pem)
  • --validity-days: CRL validity in days (default: 30)

Version

Show version information:

lab-ca version

Configuration and Templates

  • All configuration and provisioning files use HCL (HashiCorp Configuration Language).
  • Go template syntax is supported in subject, san, and other string fields. The following variables are available:
    • .Name: The certificate name (from the block label)
    • Any key from the variables map

Example:

subject = "{{ .Name }}.{{ .Domain }}"
san = ["DNS:{{ .Name }}.{{ .Domain }}"]

Certificate Types and SANs

  • server: For server certificates. SANs should be DNS or IP.
  • client: For client certificates. SANs can be email or DNS.
  • email: For S/MIME/email certificates. SANs should be email.
  • code-signing: For code signing certificates.

The tool checks that SANs are valid for the selected certificate type(s). Certificate usage can be combined (e.g. server,client).


Example: Real-World Provisioning File

See examples/example-certificates.hcl for a more advanced provisioning file with templates and variables.

Building the Tool

The repository includes a Makefile to build the CLI tool. It automatically determines the version from Git tags and builds the binary.

To build the tool, run the make command. The binary will be created as build/lab-ca.


Notes

  • The tool does not encrypt private keys. Protect your private keys directory.
  • Not intended for production use.
  • For more information about HCL, see: https://github.com/hashicorp/hcl
Description
A command-line utility that creates micro-scale Certificate Authority and generates certificates for testing purposes.
Readme MIT 328 KiB
v0.4.1 Latest
2025-12-10 21:33:23 +01:00
Languages
Go 93%
Shell 6%
Makefile 1%