Skip to content
/ certbox Public

Certbox is a lightweight REST API for managing client X.509 certificates using a custom CA.

License

Notifications You must be signed in to change notification settings

gisce/certbox

Repository files navigation

Certbox

Logo

Certbox is a lightweight REST API for managing client X.509 certificates using a custom CA. It supports issuing and revoking certificates, exporting .pfx files for browser use, and generating a CRL for mTLS setups with Nginx. Designed for simple, internal certificate workflows.

Table of Contents

Features

  • Certificate Authority Management: Automatically creates and manages a local CA
  • Client Certificate Issuance: Create X.509 client certificates for users
  • Certificate Revocation: Revoke certificates and update CRL
  • PFX Export: Export certificates as .pfx files for browser installation
  • Certificate Revocation List (CRL): Generate CRL for Nginx mTLS setups
  • Structured Storage: Organized directory structure for certificates and keys

Installation

Certbox can be used both as a REST API service and as a command-line tool. Choose the installation method that best fits your use case.

Method 1: Docker (Recommended)

  1. Clone the repository:
git clone https://github.com/gisce/certbox.git
cd certbox
  1. Build and run with Docker:
# Build the Docker image
docker build -t certbox .

# Run the service
docker run -p 8000:8000 \
  -v certbox_ca:/app/ca \
  -v certbox_crts:/app/crts \
  -v certbox_private:/app/private \
  -v certbox_clients:/app/clients \
  certbox
  1. Or use Docker Compose:
docker compose up -d

The service will be available at http://localhost:8000.

Method 2: Local Python Installation

Option A: Install from source

# Clone the repository
git clone https://github.com/gisce/certbox.git
cd certbox

# Install the package
pip install -e .

Option B: Install from PyPI (coming soon)

PyPI installation is not yet available. The package will be published to PyPI soon. Please check back for updates or use Option A to install from source in the meantime. Once installed, you can use Certbox in multiple ways:

As a CLI tool:

# Check version and available commands
certbox --help

# Create a certificate
certbox create alice

# Start the API server
certbox api --host 0.0.0.0 --port 8000

As a Python module:

# Run the API server
python -m certbox api

# Use CLI commands
python -m certbox create alice

As a traditional Python script:

# Install dependencies first
pip install -r requirements.txt

# Run the API server
python main.py

CLI Usage

Certbox provides a comprehensive command-line interface for certificate management operations. The CLI offers the same functionality as the REST API but can be used directly from the command line.

Installation for CLI Usage

To use the CLI, install Certbox using one of the methods above. The certbox command will be available system-wide after installation.

Available Commands

Global Options

The CLI supports global options that affect all commands:

# Use a custom configuration file
certbox --config /path/to/custom.env create alice

# Show help
certbox --help

# Show version  
certbox --version

Global Options:

  • --config PATH - Specify a custom configuration file (default: .env)
  • --version - Show version and exit
  • --help - Show help message

Help and Version

# Show help and available commands
certbox --help

# Show version
certbox --version

Certificate Management

Create a client certificate:

certbox create <username>

Example:

certbox create alice

Output:

✓ Certificate created successfully for user: alice
  Serial number: 12345678901234567890
  Valid from: 2023-10-03T08:12:29
  Valid until: 2024-10-03T08:12:29
  Certificate: /path/to/crts/alice.crt
  Private key: /path/to/private/alice.key
  PFX file: /path/to/clients/alice.pfx

Revoke a client certificate:

certbox revoke <username>

Example:

certbox revoke alice

Output:

✓ Certificate revoked successfully for user: alice
  Serial number: 12345678901234567890
  Revoked at: 2023-10-03T08:15:00.123456
  Status: revoked

Certificate Revocation List (CRL)

Get the current CRL:

certbox crl

You can redirect the output to save the CRL to a file:

certbox crl > crl.pem

Configuration

View current configuration:

certbox config

Output:

Current Certbox Configuration:
  Certificate validity: 365 days
  CA validity: 3650 days
  Key size: 2048 bits
  Country: ES
  State/Province: Catalonia
  Locality: Girona
  Organization: GISCE-TI
  CA Common Name: GISCE-TI CA

API Server

Start the API server:

certbox api [OPTIONS]

Options:

  • --host TEXT: Host to bind the API server to (default: 0.0.0.0)
  • --port INTEGER: Port to bind the API server to (default: 8000)

Examples:

# Start with default settings (0.0.0.0:8000)
certbox api

# Start on specific host and port
certbox api --host localhost --port 9000

# Start on all interfaces, port 8080
certbox api --host 0.0.0.0 --port 8080

CLI vs API Comparison

Operation CLI Command API Endpoint
Create certificate certbox create alice POST /certs/alice
Revoke certificate certbox revoke alice POST /revoke/alice
Renew certificate certbox renew alice POST /renew/alice
Get certificate info certbox info alice GET /certs/alice/info
Get CRL certbox crl GET /crl.pem
View config certbox config GET /config
Start server certbox api N/A

Environment Configuration for CLI

The CLI respects the same environment variables as the API server. You can configure Certbox behavior using:

# Set custom configuration for CLI operations
export CERTBOX_ORGANIZATION="My Company"
export CERTBOX_LOCALITY="Barcelona"
export CERTBOX_CERT_VALIDITY_DAYS=730
export CERTBOX_ROOT_DIR="/var/lib/certbox"

# Then use CLI commands
certbox create alice
certbox config  # Will show your custom settings

Or use a .env file in your working directory:

# Create .env file
echo "CERTBOX_ORGANIZATION=My Company" > .env
echo "CERTBOX_CERT_VALIDITY_DAYS=730" >> .env
echo "CERTBOX_ROOT_DIR=/var/lib/certbox" >> .env

# CLI commands will use these settings
certbox create alice

Or use a custom configuration file:

# Create a custom config file
cat > prod.env << EOF
CERTBOX_ROOT_DIR=/var/lib/certbox
CERTBOX_ORGANIZATION=Production Company
EOF

# Use it with the --config option
certbox --config prod.env create alice
certbox --config prod.env config

Method 2: Local Python (Legacy)

  1. Clone the repository:
git clone https://github.com/gisce/certbox.git
cd certbox
  1. Install dependencies:
pip install -r requirements.txt
  1. Run the service:
python main.py

The service will start on http://localhost:8000 and automatically create a CA if one doesn't exist.

Note: This method only provides the API server. For CLI functionality, use Method 2 installation options above.

Directory Structure

The service creates and manages the following directory structure:

certbox/
├── ca/                 # Certificate Authority files
│   ├── ca.crt         # CA certificate
│   ├── ca.key         # CA private key
│   ├── crl.pem        # Certificate Revocation List
│   └── revoked_serials.txt # List of revoked certificate serials
├── crts/              # Client certificates
├── private/           # Client private keys
├── clients/           # PFX files for browser installation
└── requests/          # Certificate signing requests (future use)

Docker Volumes

When using Docker, these directories are mounted as persistent volumes:

  • certbox_ca - Contains the CA certificate, key and CRL
  • certbox_crts - Contains client certificates
  • certbox_private - Contains client private keys
  • certbox_clients - Contains PFX files for browser installation
  • certbox_requests - Contains certificate signing requests

These volumes ensure data persistence across container restarts.

API Endpoints

Root Endpoint

  • GET / - Service information and available endpoints

Certificate Management

  • POST /certs/{username} - Create a new client certificate
  • POST /revoke/{username} - Revoke a client certificate
  • POST /renew/{username} - Renew a client certificate
  • GET /certs/{username}/info - Get information about a certificate
  • GET /certs/{username}/pfx - Download PFX file for browser installation

Certificate Revocation List

  • GET /crl.pem - Download the current CRL in PEM format

Configuration

  • GET /config - View current configuration settings

Usage Examples

Certbox provides both REST API and CLI interfaces. Choose the method that works best for your workflow.

API Examples

Create a certificate

# Without authentication (when CERTBOX_API_TOKEN is not set)
curl -X POST http://localhost:8000/certs/alice

# With authentication (when CERTBOX_API_TOKEN is configured)
curl -X POST -H "Authorization: Bearer your-secret-token" http://localhost:8000/certs/alice

Response:

{
    "username": "alice",
    "serial_number": "12345678901234567890",
    "valid_from": "2023-10-03T08:12:29",
    "valid_until": "2024-10-03T08:12:29",
    "certificate_path": "/path/to/crts/alice.crt",
    "private_key_path": "/path/to/private/alice.key",
    "pfx_path": "/path/to/clients/alice.pfx",
    "pfx_password": "c^016iKp6vx0"
}

Download PFX file for browser installation

# Without authentication (when CERTBOX_API_TOKEN is not set)
curl -O -J http://localhost:8000/certs/alice/pfx

# With authentication (when CERTBOX_API_TOKEN is configured)
curl -O -J -H "Authorization: Bearer your-secret-token" http://localhost:8000/certs/alice/pfx

Note: PFX files are password-protected for security. The password is provided in the response when creating or renewing certificates (see pfx_password field above). You'll need this password to import the PFX file into your browser.

Revoke a certificate

# Without authentication (when CERTBOX_API_TOKEN is not set)
curl -X POST http://localhost:8000/revoke/alice

# With authentication (when CERTBOX_API_TOKEN is configured)
curl -X POST -H "Authorization: Bearer your-secret-token" http://localhost:8000/revoke/alice

Response:

{
    "username": "alice",
    "serial_number": "12345678901234567890",
    "revoked_at": "2023-10-03T08:15:00.123456",
    "status": "revoked"
}

Download CRL for Nginx configuration

curl -O http://localhost:8000/crl.pem

Get certificate information

# Without authentication (when CERTBOX_API_TOKEN is not set)
curl http://localhost:8000/certs/alice/info

# With authentication (when CERTBOX_API_TOKEN is configured)
curl -H "Authorization: Bearer your-secret-token" http://localhost:8000/certs/alice/info

Response:

{
    "username": "alice",
    "serial_number": "12345678901234567890",
    "status": "valid",
    "valid_from": "2023-10-03T08:12:29+00:00",
    "valid_until": "2024-10-03T08:12:29+00:00",
    "is_revoked": false,
    "subject": {
        "country": "ES",
        "state_province": "Catalonia",
        "locality": "Girona",
        "organization": "GISCE-TI",
        "common_name": "alice"
    },
    "issuer": {
        "organization": "GISCE-TI",
        "common_name": "GISCE-TI CA"
    },
    "certificate_path": "/path/to/crts/alice.crt",
    "private_key_path": "/path/to/private/alice.key",
    "pfx_path": "/path/to/clients/alice.pfx",
    "key_usage": {
        "digital_signature": true,
        "key_encipherment": true,
        "key_agreement": false,
        "key_cert_sign": false,
        "crl_sign": false,
        "content_commitment": false,
        "data_encipherment": false
    },
    "extensions": {
        "basic_constraints": {
            "ca": false,
            "path_length": null
        },
        "extended_key_usage": ["clientAuth"],
        "subject_key_identifier": "a1b2c3d4e5f6...",
        "authority_key_identifier": "f6e5d4c3b2a1..."
    }
}

CLI Examples

The CLI provides the same functionality with a more direct interface:

Create a certificate

certbox create alice

Revoke a certificate

certbox revoke alice

Get certificate information

certbox info alice

Output:

Certificate Information for user: alice
  Serial number: 12345678901234567890
  Status: valid
  Valid from: 2023-10-03T08:12:29+00:00
  Valid until: 2024-10-03T08:12:29+00:00
  Is revoked: False
  Subject:
    Country: ES
    State Province: Catalonia
    Locality: Girona
    Organization: GISCE-TI
    Common Name: alice
  Issuer:
    Organization: GISCE-TI
    Common Name: GISCE-TI CA
  File paths:
    Certificate: /path/to/crts/alice.crt
    Private key: /path/to/private/alice.key
    PFX file: /path/to/clients/alice.pfx
  Key usage:
    ✓ Digital Signature
    ✓ Key Encipherment
  Extensions:
    Basic Constraints:
      ca: False
      path_length: None
    Extended Key Usage: clientAuth
    Subject Key Identifier: a1b2c3d4e5f6...
    Authority Key Identifier: f6e5d4c3b2a1...

Get CRL (output to stdout)

certbox crl

# Save to file
certbox crl > crl.pem

View configuration

certbox config

Start API server

certbox api --host 0.0.0.0 --port 8000

Browser Certificate Import

Importing PFX Files

The generated PFX files are password-protected and can be imported into browsers for client certificate authentication:

Chrome/Edge

  1. Go to Settings → Privacy and security → Security → Manage certificates
  2. Click "Import" in the Personal tab
  3. Select the downloaded .pfx file
  4. Enter the password provided in the API response (pfx_password field)
  5. Complete the import wizard

Firefox

  1. Go to Settings → Privacy & Security → Certificates → View Certificates
  2. Click "Import" in the Your Certificates tab
  3. Select the downloaded .pfx file
  4. Enter the password provided in the API response
  5. The certificate will be available for client authentication

Safari (macOS)

  1. Double-click the downloaded .pfx file
  2. Enter the password when prompted
  3. Choose the keychain to import to (usually "login")
  4. The certificate will be available in Keychain Access and Safari

Important: Keep the password secure as it protects your private key. The password is only provided when creating or renewing certificates.

Nginx mTLS Configuration

To use the generated certificates and CRL with Nginx for mutual TLS authentication:

server {
    listen 443 ssl;
    server_name example.com;
    
    # Server certificate
    ssl_certificate /path/to/server.crt;
    ssl_certificate_key /path/to/server.key;
    
    # Client certificate verification
    ssl_client_certificate /path/to/certbox/ca/ca.crt;
    ssl_verify_client on;
    ssl_crl /path/to/certbox/ca/crl.pem;
    
    location / {
        # Your application
        proxy_pass http://backend;
        
        # Pass client certificate info to backend
        proxy_set_header X-Client-DN $ssl_client_s_dn;
        proxy_set_header X-Client-Verify $ssl_client_verify;
    }
}

Testing

Run the included test suite with pytest:

# Install testing dependencies
pip install -r requirements-dev.txt

# Run API tests
pytest tests/test_api.py -v

# Run CLI tests
pytest tests/test_cli.py -v

# Run all tests
pytest tests/ -v

# Or run with the original method (deprecated)
python tests/test_api.py

The test suite includes:

  • API endpoint testing - REST API functionality and responses
  • CLI command testing - Command-line interface functionality
  • Configuration validation - Environment and .env file configuration
  • Certificate manager functionality - Core certificate operations
  • Python version compatibility checks - Support for Python 3.8+
  • Integration tests with mocked dependencies - Isolated testing without external dependencies

Tests are also run automatically via GitHub Actions on Python 3.8, 3.9, 3.10, 3.11, and 3.12.

Versioning and Releases

Certbox follows Semantic Versioning and uses an automated hybrid versioning system that combines conventional commits with manual label overrides.

How It Works

  1. Automatic Version Detection: The system analyzes commit messages following Conventional Commits format:

    • feat: → Minor version bump (new features)
    • fix: → Patch version bump (bug fixes)
    • feat! or BREAKING CHANGE: → Major version bump (breaking changes)
  2. Manual Override: You can override automatic detection by adding exactly one release label to your PR:

    • release:major → Major version bump (x.0.0)
    • release:minor → Minor version bump (x.y.0)
    • release:patch → Patch version bump (x.y.z)
  3. Validation: All PRs are automatically validated to ensure consistency between commits and labels.

Release Process

When a PR is merged to main, the system automatically:

  • ✅ Determines the appropriate version bump
  • ✅ Updates the version in certbox/__init__.py
  • ✅ Generates/updates the CHANGELOG.md
  • ✅ Creates a git tag
  • ✅ Creates a GitHub release
  • ✅ Publishes to PyPI (if configured)

Contributing Guidelines

When contributing to Certbox:

  1. Use Conventional Commits (recommended):

    feat(api): add certificate renewal endpoint
    fix(cli): resolve config file parsing issue
    docs: update installation instructions
    
  2. Or use Release Labels: Add exactly one label (release:major, release:minor, or release:patch) to your PR

  3. Breaking Changes: Use feat!: or include BREAKING CHANGE: in the commit body, or add release:major label

  4. Edge Cases:

    • Documentation-only changes → release:patch or will default to patch
    • Internal refactoring → refactor: (patch) or release:patch if breaking
    • CI/build changes → ci: or build: (patch)

The PR validation system will check your changes and provide feedback on the expected version bump.

Configuration

The service can be configured using environment variables or a .env file. All settings have sensible defaults:

Certificate Settings

  • CERTBOX_CERT_VALIDITY_DAYS - Client certificate validity in days (default: 365)
  • CERTBOX_CA_VALIDITY_DAYS - CA certificate validity in days (default: 3650)
  • CERTBOX_KEY_SIZE - RSA key size in bits (default: 2048)
  • CERTBOX_PFX_PASSWORD_LENGTH - PFX file password length (default: 12)

API Authentication

  • CERTBOX_API_TOKEN - API authentication token (default: "" - authentication disabled)

When CERTBOX_API_TOKEN is set, the following endpoints require authentication:

  • POST /certs/{username} - Create certificate
  • POST /revoke/{username} - Revoke certificate
  • GET /certs/{username}/pfx - Download PFX file

Public endpoints (no authentication required):

  • GET / - Service information
  • GET /config - Configuration view
  • GET /crl.pem - Certificate revocation list

Certificate Subject Information

  • CERTBOX_COUNTRY - Country code (default: "ES")
  • CERTBOX_STATE_PROVINCE - State or province (default: "Catalonia")
  • CERTBOX_LOCALITY - City or locality (default: "Girona")
  • CERTBOX_ORGANIZATION - Organization name (default: "GISCE-TI")
  • CERTBOX_CA_COMMON_NAME - CA common name (default: "GISCE-TI CA")

Directory Configuration

  • CERTBOX_ROOT_DIR - Root directory for all certificate files (default: project directory)

When CERTBOX_ROOT_DIR is set, all certificate directories (ca/, crts/, private/, clients/, requests/) will be created under this path instead of the project directory.

Configuration Methods

Method 1: Environment Variables

# Run with custom configuration including authentication
CERTBOX_ORGANIZATION="My Company" \
CERTBOX_LOCALITY="Barcelona" \
CERTBOX_CERT_VALIDITY_DAYS=730 \
CERTBOX_ROOT_DIR="/var/lib/certbox" \
CERTBOX_API_TOKEN="my-secret-api-token" \
python main.py

Method 2: .env File

Create a .env file in the project root directory:

# .env file
CERTBOX_CERT_VALIDITY_DAYS=730
CERTBOX_CA_VALIDITY_DAYS=7300
CERTBOX_COUNTRY=ES
CERTBOX_STATE_PROVINCE=Catalonia
CERTBOX_LOCALITY=Barcelona
CERTBOX_ORGANIZATION=My Company
CERTBOX_CA_COMMON_NAME=My Company CA
CERTBOX_KEY_SIZE=4096
CERTBOX_ROOT_DIR=/var/lib/certbox

Or copy and modify the example file:

cp .env.example .env
# Edit .env with your preferred values

Then simply run:

python main.py

Note: Environment variables take precedence over .env file values.

Method 3: Custom Configuration File

You can specify a custom configuration file using the CLI --config option:

# Create a custom config file
cat > /etc/certbox/production.env << EOF
CERTBOX_ROOT_DIR=/var/lib/certbox
CERTBOX_ORGANIZATION=Production Company
CERTBOX_CERT_VALIDITY_DAYS=365
CERTBOX_CA_VALIDITY_DAYS=3650
EOF

# Use the custom config file with CLI
certbox --config /etc/certbox/production.env create alice
certbox --config /etc/certbox/production.env config

This method is particularly useful for:

  • Production deployments with specific configurations
  • Multiple environments (dev, staging, production)
  • Shared team configurations
  • System-wide installations

Example Usage

Using environment variables:

# Run with custom configuration including custom storage location
CERTBOX_ORGANIZATION="My Company" \
CERTBOX_LOCALITY="Barcelona" \
CERTBOX_CERT_VALIDITY_DAYS=730 \
CERTBOX_ROOT_DIR="/var/lib/certbox" \
python main.py

Using .env file:

# Create .env file with your configuration
echo "CERTBOX_ORGANIZATION=My Company" > .env
echo "CERTBOX_LOCALITY=Barcelona" >> .env
echo "CERTBOX_CERT_VALIDITY_DAYS=730" >> .env
echo "CERTBOX_ROOT_DIR=/var/lib/certbox" >> .env

# Run the service
python main.py

Using custom config file with CLI:

# Create a custom configuration file
cat > custom.env << EOF
CERTBOX_ROOT_DIR=/tmp/test_certs
CERTBOX_ORGANIZATION=Test Company
EOF

# Use custom config with CLI commands
certbox --config custom.env create testuser
certbox --config custom.env config

Configuration Endpoint

You can view the current configuration by accessing the /config endpoint:

curl http://localhost:8000/config

Response:

{
    "cert_validity_days": 365,
    "ca_validity_days": 3650,
    "key_size": 2048,
    "country": "ES",
    "state_province": "Catalonia",
    "locality": "Girona",
    "organization": "GISCE-TI",
    "ca_common_name": "GISCE-TI CA"
}

Note: When CERTBOX_ROOT_DIR is configured, the response will also include:

{
    "cert_validity_days": 365,
    "ca_validity_days": 3650,
    "key_size": 2048,
    "country": "ES",
    "state_province": "Catalonia",
    "locality": "Girona",
    "organization": "GISCE-TI",
    "ca_common_name": "GISCE-TI CA",
    "root_dir": "/var/lib/certbox"
}

Security Notes

  • The CA private key is stored unencrypted for simplicity
  • This service is designed for internal use cases
  • For production use, consider implementing proper authentication and authorization
  • Regularly backup the CA directory

License

MIT License - see LICENSE file for details.

About

Certbox is a lightweight REST API for managing client X.509 certificates using a custom CA.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •