6.8 KiB
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> ...] [--overwrite] [--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
)--overwrite
: Allow overwriting existing files--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> [--overwrite] [--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 build.sh
script to build the CLI tool. It updates the version in version.go
and builds the binary.
To ignore changes made to version.go
in Git, you can run:
git update-index --assume-unchanged version.go
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