goselfca
goselfca is a simple, zero-dependency Certificate Authority (CA) generator built in Go. It is designed for use cases where the CA operator also operates each host where a certificate will be used, such as internal microservices, RPC systems, local development environments, and IoT devices.
Instead of writing complex OpenSSL bash scripts, goselfca automatically generates both a private key and a valid certificate in a single command.
Features
- Modern Cryptography: Supports
Ed25519 (default), ECDSA (P-384), and RSA (2048-bit) algorithms.
- Certificate Profiles: Generate certificates tailored for your use case:
server (default): TLS Web Server Authentication
client: TLS Web Client Authentication
peer: Both Server and Client Authentication (perfect for Mutual TLS / mTLS)
- Customizable Validity: Configure the exact TTL of both the Root CA and the generated leaf certificates.
- Subject Customization: Easily inject Subject
Organization (O) and Organizational Unit (OU) fields for clean logs and network debugging.
- High Entropy: Uses 128-bit randomly generated serial numbers to prevent collision attacks.
- Idempotent by Default: Reuses existing Root CA keys and certificates if they exist in the directory.
Note: goselfca acts as a developer-friendly Root CA. It does not offer OCSP or CRL services.
Installation
Ensure you have Go installed, then run:
go install github.com/ashishtaldeokar/goselfca@latest
Quick Start
Generate a new Root CA and a Server Certificate for example.com:
goselfca --domains "example.com"
This will:
- Generate
goselfca-key.pem and goselfca.pem (Your Root CA) in the current directory if they don't exist.
- Create a new directory named
example.com.
- Generate
key.pem and cert.pem inside example.com/ signed by your Root CA.
Advanced Usage
1. Generating a Client Certificate for mTLS
If you are building an mTLS system (like a gRPC mesh), you can generate a certificate with the client profile:
goselfca --domains "service-a.local" --profile client
Or a peer certificate for nodes that act as both clients and servers:
goselfca --domains "node-1.raft.local" --profile peer
2. Customizing Validity Periods
The default validity for the Root CA is 100 years, and leaf certificates default to 2 years and 30 days (to satisfy macOS/iOS constraints). You can customize these using Go's duration strings (e.g., h for hours):
# Generate a short-lived certificate valid for only 24 hours
goselfca --domains "ephemeral.internal" --validity 24h
# Generate a Root CA valid for only 1 year (8760 hours)
goselfca --domains "ephemeral.internal" --ca-validity 8760h
When managing multiple certificates, it helps to identify them by their Organization (O) or Organizational Unit (OU):
goselfca --domains "*.internal.company.com" \
--org "Company Inc." \
--unit "Backend Engineering"
4. Specifying IP Addresses
You can generate certificates bound to an IP address instead of a DNS name. Or both!
goselfca --domains "localhost" --ip-addresses "127.0.0.1,10.0.0.5"
5. Using Legacy Algorithms (RSA, ECDSA)
By default, goselfca uses Ed25519. If you are working with older systems that do not support Ed25519, you can switch the algorithm:
goselfca --domains "legacy.local" --ca-alg rsa
Trusting the CA
To make your browser or operating system trust the certificates generated by goselfca, you must add the Root CA (goselfca.pem) to your system's trust store.
macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain goselfca.pem
macOS Compatibility Note: Apple's Keychain Access currently does not support importing Ed25519 Root CA certificates. If you try to add the default Ed25519 goselfca.pem, you will receive Error: -25257 (Unknown format in import).
To generate certificates that macOS will trust, you must use ECDSA or RSA:
goselfca --domains "example.com" --ca-alg ecdsa
Linux (Ubuntu/Debian):
sudo cp goselfca.pem /usr/local/share/ca-certificates/goselfca.crt
sudo update-ca-certificates
Windows:
Import-Certificate -FilePath "goselfca.pem" -CertStoreLocation cert:\LocalMachine\Root
CLI Tools (curl, wget, etc.):
Many command-line tools (especially curl installed via Homebrew on macOS) use their own internal certificate bundles and will ignore the system Keychain. This causes curl: (60) SSL certificate problem: unable to get local issuer certificate errors even after completing the OS importing steps above.
To fix this, explicitly provide the Root CA using a flag or an environment variable:
# Option 1: Explicitly pass the Root CA via flag
curl --cacert goselfca.pem https://example.com/
# Option 2: Set the environment variable for your session
export CURL_CA_BUNDLE=/path/to/goselfca.pem
curl https://example.com/
Integration Examples
Nginx
To use your generated certificate with Nginx, modify your server block to point ssl_certificate and ssl_certificate_key to your generated files. Since goselfca uses modern cryptography (Ed25519 by default), ensure your Nginx configuration allows modern TLS protocols and ciphers.
Important: If you experience an ERR_SSL_VERSION_OR_CIPHER_MISMATCH error with Nginx, it is likely because your Nginx/OpenSSL build does not support Ed25519 certificates. In this case, generate an ECDSA certificate instead using:
goselfca --domains "example.com" --ca-alg ecdsa
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/example.com/cert.pem;
ssl_certificate_key /path/to/example.com/key.pem;
# Enable modern TLS versions
ssl_protocols TLSv1.2 TLSv1.3;
# Enable modern ciphers (required for Ed25519/ECDSA)
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8080;
}
}
Trust Store Tip: For clients (browsers, IoT devices, or other microservices) to trust this Nginx server, you must install the Root CA (goselfca.pem) into their respective trust stores, not the cert.pem.
HAProxy
HAProxy requires the certificate and the private key to be bundled together into a single PEM file.
First, concatenate the certificate and the key:
cat example.com/cert.pem example.com/key.pem > example.com/haproxy.pem
Then, configure HAProxy to use the bundled PEM file in your frontend or listen block:
frontend https_front
bind *:443 ssl crt /path/to/example.com/haproxy.pem
default_backend web_servers
backend web_servers
server web1 127.0.0.1:8080
Trust Store Tip: For clients to trust your HAProxy server, you must install the Root CA (goselfca.pem) into their system trust stores, not the bundled haproxy.pem.
License
MIT License