A personal CLI wrapper because lifeβs too short for OpenSSL flags.
I built this tool for myself because I was tired of:
So I made igcv3: a cross-platform, OpenSSL-free, RFC-compliant PKI toolkit (IGC is the French translation of PKI, hence the name, because I am a frenchie =ΓΎ).
Itβs the fruit of pure laziness: I just donβt want to remember things. π
# Instead of this nightmare:
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr \
-subj "/C=FR/ST=IDF/L=Paris/O=MyCompany/CN=www.example.com" \
-addext "subjectAltName=DNS:www.example.com,DNS:example.com,IP:192.168.1.1" \
-addext "keyUsage=digitalSignature,keyEncipherment" \
-addext "extendedKeyUsage=serverAuth"
# (To be fair: OpenSSL supports config files, which helps. Still, it's easy to end up juggling flags and SAN syntax.)
# Just do this:
igc generate www.example.com
| Task | OpenSSL | igcv3 |
|---|---|---|
| Convert PEM to DER | openssl x509 -in cert.pem -outform... |
igc read cert.pem --out cert.der |
| Inspect a certificate | openssl x509 -in cert.pem -text -noout |
igc read cert.pem |
| Generate a web server CSR | 5+ flags, manual SAN syntax | igc gen my.domain --preset web-modern * |
| Fetch a remote certificate | openssl s_client -connect... + parsing |
igc get google.com --chain |
| Build a certificate chain | Manual concatenation + order guessing | igc bundle --auto *.pem |
igc generate already selects a usable default preset (e.g., web-standard), so --preset is only needed when you want another profile like web-modern.inspect and --silent mode for scriptsnode-forge and @peculiar/x509.# From npm (recommended)
npm install -g igcv3
# From source
git clone https://github.com/KaminoU/igcv3.git
cd igcv3
npm install
npm run build
npm link
igcv3 implements a Hybrid CLI pattern: commands work both as traditional CLI tools AND as interactive wizards.

# Full CLI mode (for scripting)
igc generate api.example.com --preset web-standard --out ./certs --silent
# Full interactive mode (for exploration)
igc generate
# β Prompts for CN, preset, SANs, output directory...
# Hybrid mode (best of both worlds)
igc generate --preset web-modern
# β Only CN is missing, prompts just for: "Common Name (CN):"
Custom Preset Example:
For full configuration options, see
examples/igcv3.conf.yml
# =============================================================================
# 3. PKI Settings (Content)
# =============================================================================
pki:
interactive: true # If false, fail instead of prompting for missing variables
sanitizeName: true # If true, auto-fix CN for DNS (e.g. "My Site" -> "my-site"). If false, fail on invalid chars.
mergePresets: false # If false, local config replaces default presets instead of merging.
defaults:
countryName: 'FR'
stateOrProvinceName: 'Ile-de-France'
localityName: 'Paris'
organizationName: 'My Company'
organizationalUnitName: 'IT'
validityDays: 365
# -----------------------------------------------------------------------------
# 5. Presets (Certificate Templates)
# -----------------------------------------------------------------------------
presets:
dynamic:
description: 'A custom preset with dynamic variables'
variables:
PROJECT:
type: 'input'
message: 'Project Name'
ENV:
type: 'list'
message: 'Environment'
choices: ['DEV', 'INT', 'PROD']
validityDays: 90 # Let's Encrypt constraint
organizationalUnitName:
- '001-AAA'
- 'LETS ENCRYPT TEST'
- '-'
subjectAltName:
templates:
- 'DNS:'
Batch Manifest Example:
For industrial-scale certificate generation, use a manifest file to generate multiple CSRs in a single run:
# =============================================================================
# IGCV3 Batch Generation Manifest
# =============================================================================
# Usage: igc gen --manifest manifest.yml
#
# This example uses the 'dynamic' preset defined above, which requires two
# variables (PROJECT and ENV). This serves a dual purpose:
# 1. Validate that your preset configuration works correctly
# 2. Test all supported key algorithms in one batch
#
# For internal/enterprise CAs: all subject fields (O, OU, etc.) will be
# preserved in the signed certificate.
#
# For Let's Encrypt (DV): only CN and SANs are kept in the final certificate,
# but the CSR generation still validates your preset works as expected.
#
# As of late 2025, Let's Encrypt does NOT support:
# - ECDSA P-521 (too "exotic" for Web PKI standards)
# - Ed25519 (not yet accepted by CA/B Forum for public SSL)
# =============================================================================
- cn: 'example.com'
key:
algo: 'rsa'
size: 2048
preset: 'dynamic'
vars:
PROJECT: 'VALIDATION RSA 2048'
ENV: 'DEV'
output:
dir: './certs'
filename: 'rsa2048'
- cn: 'example.com'
key:
algo: 'rsa'
size: 4096
preset: 'dynamic'
vars:
PROJECT: 'VALIDATION RSA 4096'
ENV: 'DEV'
output:
dir: './certs'
filename: 'rsa4096'
- cn: 'example.com'
key:
algo: 'ecdsa'
curve: 'P-256'
preset: 'dynamic'
vars:
PROJECT: 'VALIDATION ECDSA P-256'
ENV: 'PROD'
output:
dir: './certs'
filename: 'ecdsa256'
- cn: 'example.com'
key:
algo: 'ecdsa'
curve: 'P-384'
preset: 'dynamic'
vars:
PROJECT: 'VALIDATION ECDSA P-384'
ENV: 'PROD'
output:
dir: './certs'
filename: 'ecdsa384'
This design philosophy applies to all commands: generate, inspect, get, bundle, and scaffold.
| Command | Alias | Purpose |
|---|---|---|
generate |
gen |
Create keys and CSRs |
inspect |
read |
Analyze certificates and CSRs |
get |
- | Fetch remote certificates |
bundle |
- | Build certificate chains |
scaffold |
- | Generate config templates |
These options are available on all commands:
| Option | Description |
|---|---|
-c, --config <path> |
Path to custom configuration file |
-d, --debug |
Enable verbose debugging output |
-s, --silent |
Suppress banner and non-essential output |
-i, --info |
Show application information |
-l, --log-level <level> |
Set log level (debug, info, warn, error, silent) |
Below are task-oriented examples for each command. You can omit arguments to enter interactive mode.
generate / gen - Create Keys & CSRsigc gen www.example.com
igc gen my.private.machine --preset machine --vars PROJECT="A Secret Project" ENV="DEV" IP_ADDRESS="192.168.3.3"
Manual mode (full CLI):

Interactive wizard mode:

Batch manifest mode:

get - Fetch Remote Certificatesigc get google.com --chain --out google.chain.pem
igc get imap.gmail.com:993 --out imap.gmail.pem
inspect / read - Analyze Certificates & CSRsigc read cert.pem --json
igc read cert.pem --out cert.der
#!/bin/zsh
# Match csr (or cert) to its private key
csrs=(*.csr)
keys=(*.key)
for key in $keys; do
echo "π Checking key: $key"
for (( i=1; i <= $#csrs; i++ )); do
csr=$csrs[$i]
match=$(igc read "$csr" --key "$key" --match-only 2>/dev/null)
# or
# match=$(igc read "$csr" --key "$key" --json 2>/dev/null | jq -r '.keyVerification.match')
if [[ "$match" == "true" ]]; then
echo " β
Match -> $csr"
csrs[$i]=()
break # Comment it out if one key can match multiple CSRs/Certs
fi
done
done

bundle - Build Certificate Chainsigc bundle --auto my.site* --out fullchain.pem # Auto-detect and sort (magic!) - I told you, lazy am I... π
igc bundle leaf.pem --intermediate inter1.pem inter2.pem ... intern.pem --root root.pem --out chain.pem
β οΈ Performance note:
bundle --autois meant for a chain-sized handful of files. If you point it at a folder with 25,000 PEMs, it will (politely) take its time. Prefer tighter globs (likemy.site*above) rather than*.pem, or use--chainfor explicit inputs.
scaffold - Generate Config Templatesigc scaffold --template config
igc scaffold --template manifest
| Algorithm | Key Generation | CSR Generation | Certificate Reading |
|---|---|---|---|
| RSA 2048 | β | β | β |
| RSA 4096 | β | β | β |
| ECDSA P-256 | β | β | β |
| ECDSA P-384 | β | β | β |
| ECDSA P-521 | β | β | β |
| Ed25519 | β | β | β |
π‘ Tip: Use
web-modernpreset for ECDSA P-256 (recommended by Letβs Encrypt for performance).β οΈ Note on Ed25519: While igcv3 fully supports Ed25519 for key/CSR generation and certificate reading, no public Certificate Authority currently issues Ed25519 TLS certificates. Ed25519 is primarily used for SSH keys, code signing, and internal PKI. For public web servers, use ECDSA P-256 or RSA.
igcv3 is a Node.js, config-driven application. Create at least the main configuration file (igcv3.conf.yml) to get started; scaffold makes it easy and safe.
igcv3 uses three YAML configuration files:
| File | Purpose |
|---|---|
igcv3.conf.yml |
Main config with org defaults and reusable presets. Supports cascade loading (local β user β system). |
manifest.template.yml |
Batch CSR generation. Define multiple certificates with their presets for fully automated, non-interactive runs. |
chain.conf.yml |
Bundle config. Define certificate chain paths for those who prefer explicit over --auto. |
# Generate starter configs
igc scaffold --template config # β igcv3.conf.yml
igc scaffold --template manifest # β manifest.template.yml
igc scaffold --template chain # β chain.conf.yml
igc scaffold --template all # β all three
π Click on the file names above or browse the
examples/folder for fully commented samples.
As a RFC-compliant tool, igcv3 works seamlessly with Letβs Encrypt ACME validation. Hereβs a typical workflow:
Generate a CSR for your domain:
igc generate example.com --preset web-modern
igc inspect path/to/your.csr.Request the certificate via certbot:
certbot certonly --manual --csr example.com.csr --preferred-challenges dns
π‘ Tip: Use
--preset web-modernfor ECDSA P-256, recommended by Letβs Encrypt for performance.
Unit tests (Jest) and end-to-end tests (PowerShell) cover core logic and CLI workflows.
npm test # Unit tests (Jest)
npm test -- --coverage # Coverage
./tests/main.ps1 # E2E/integration tests (PowerShell)
./tests/main.ps1 -Verbose # With detailed output
| Suite | Description |
|---|---|
| 01 | Global CLI options |
| 02 | Scaffold command |
| 03 | Get command (remote TLS) |
| 04 | Inspect command + JSON + algorithms |
| 05 | Bundle command + auto-sort + glob |
| 06 | Generate command + RSA/ECDSA/Ed25519 |
Note: Unit tests focus on pure logic; interactive flows are exercised in the PowerShell E2E suites. Some edge cases can still slip through ; if you find a bug, please open an issue. π
| Feature | Status | Notes |
|---|---|---|
| TLS Implicit (443, 993, 995) | β Supported | Direct TLS connection |
| STARTTLS (587, 143, 110) | β Not supported | Requires protocol handshake |
| Hardware tokens (HSM, YubiKey) | β Not planned | PKCS#11 not in scope |
These features are not essential but would be nice additions. Contributions welcome! πβ€οΈ
igcv3/
βββ src/
β βββ commands/ # CLI command implementations
β β βββ generate/ # Generate command (modular)
β β βββ inspect/ # Inspect command (modular)
β βββ config/ # Configuration loading & validation
β βββ lib/ # Business logic (chain validation, etc.)
β βββ services/ # PKI services (RSA, ECC providers)
β βββ types/ # Local type overrides / shims
β βββ utils/ # Shared utilities (logger, formatting)
βββ tests/
β βββ fixtures/ # Test data (configs, certificates)
β βββ lib/ # PowerShell test helpers
β βββ output/ # Generated test artifacts (gitignored)
β βββ suites/ # PowerShell integration tests
βββ examples/ # Example configuration files
Key Design Decisions:
PkiService provides a unified API over multiple crypto backendsContributions are welcome! Hereβs how to get started:
git clone https://github.com/KaminoU/igcv3.git
cd igcv3
npm install
npm run build
npm link # Makes 'igc' available globally for testing
npm test # Unit tests (watch mode: npm test -- --watch)
./tests/main.ps1 -Verbose # Integration tests
noImplicitAny)npm run lint)Add feature, not Added feature)git checkout -b feature/amazing-feature)npm test && ./tests/main.ps1)See CONTRIBUTING.md for detailed guidelines.
MIT Β© 2025
Made with β€οΈ by a lazy guy, for all lazy buds everywhere. ^^