igcv3

Infrastructure for Key Management

A personal CLI wrapper because life’s too short for OpenSSL flags.

npm version Node.js TypeScript Build Tests Documentation License

🎯 What is igcv3?

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

TL;DR: The Elevator Pitch

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

✨ Key Features

πŸ“¦ Installation

# 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

πŸ”„ Hybrid CLI Mode

igcv3 implements a Hybrid CLI pattern: commands work both as traditional CLI tools AND as interactive wizards.

Main Menu

# 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.

πŸ› οΈ Commands

Command Summary

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

Global Options

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)

Practical Examples

Below are task-oriented examples for each command. You can omit arguments to enter interactive mode.

generate / gen - Create Keys & CSRs

igc 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):

Generate Manual

Interactive wizard mode:

Generate Wizard

Batch manifest mode:

Generate Manifest

get - Fetch Remote Certificates

igc get google.com --chain --out google.chain.pem
igc get imap.gmail.com:993 --out imap.gmail.pem

inspect / read - Analyze Certificates & CSRs

igc 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

Get Inspect

bundle - Build Certificate Chains

igc 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 --auto is 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 (like my.site* above) rather than *.pem, or use --chain for explicit inputs.

scaffold - Generate Config Templates

igc scaffold --template config
igc scaffold --template manifest

πŸ” Supported Algorithms

Algorithm Key Generation CSR Generation Certificate Reading
RSA 2048 βœ… βœ… βœ…
RSA 4096 βœ… βœ… βœ…
ECDSA P-256 βœ… βœ… βœ…
ECDSA P-384 βœ… βœ… βœ…
ECDSA P-521 βœ… βœ… βœ…
Ed25519 βœ… βœ… βœ…

πŸ’‘ Tip: Use web-modern preset 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.

βš™οΈ Configuration

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.

πŸ“ Using with Let’s Encrypt

As a RFC-compliant tool, igcv3 works seamlessly with Let’s Encrypt ACME validation. Here’s a typical workflow:

  1. Generate a CSR for your domain:

    igc generate example.com --preset web-modern
    
  2. (Optional) Verify your CSR at certlogik.com/decoder (independent check). For a quick local sanity check, you can also use igc inspect path/to/your.csr.
  3. Request the certificate via certbot:

    certbot certonly --manual --csr example.com.csr --preferred-challenges dns
    
  4. Complete the DNS challenge: Add the TXT record provided by certbot.
  5. Retrieve your certificates: certbot creates the signed certificate + intermediate chain via ACME.

πŸ’‘ Tip: Use --preset web-modern for ECDSA P-256, recommended by Let’s Encrypt for performance.

πŸ§ͺ Testing

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. πŸ›

🚧 Known Limitations

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

πŸ—ΊοΈ Roadmap (Nice-to-Have)

These features are not essential but would be nice additions. Contributions welcome! πŸŽ‰β€οΈ

πŸ—οΈ Project Architecture

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:

πŸ‘₯ Contributing

Contributions are welcome! Here’s how to get started:

Development Setup

git clone https://github.com/KaminoU/igcv3.git
cd igcv3
npm install
npm run build
npm link  # Makes 'igc' available globally for testing

Running Tests

npm test                    # Unit tests (watch mode: npm test -- --watch)
./tests/main.ps1 -Verbose  # Integration tests

Code Style

Pull Request Process

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for your changes
  4. Ensure all tests pass (npm test && ./tests/main.ps1)
  5. Submit a PR with a clear description

See CONTRIBUTING.md for detailed guidelines.

πŸ“„ License

MIT Β© 2025


Made with ❀️ by a lazy guy, for all lazy buds everywhere. ^^