Skip to main content

Cloudflare Request Cert

Python Version PyPI PyPI Downloads Build Coverage License

A Python tool for requesting and renewing SSL/TLS certificates using Cloudflare DNS API with Let's Encrypt. Built with modern Python tooling using uv for fast dependency management.

Disclaimer: This project is not affiliated with, endorsed by, or supported by Cloudflare.

Features

  • 🔒 Automated SSL/TLS certificate requests using DNS-01 challenge
  • ☁️ Cloudflare DNS API integration
  • ⚡ Fast dependency management with uv
  • 🛠️ Simple Makefile interface
  • 🔄 Compatible with certbot's automatic renewal
  • 🧪 Staging environment support for testing
  • 📝 Configuration via .env file or command-line arguments
  • 🔧 Flexible: use .env, CLI args, or both

Prerequisites

  • Python 3.10 or higher
  • A Cloudflare account with API token
  • Domain managed by Cloudflare DNS

Installation

Quick Setup

# Install dependencies (will install uv if not present)
make install

Manual uv Installation

If you prefer to install uv manually:

curl -LsSf https://astral.sh/uv/install.sh | sh

Configuration

1. Get Cloudflare API Token

  1. Log in to your Cloudflare dashboard
  2. Go to My Profile → API Tokens
  3. Create a token with these permissions:
    • Zone:DNS:Edit for the zones you want to manage
    • Zone:Zone:Read for all zones

2. Set Up Credentials

Create a .env file in the project root:

# Copy the example file
cp .env.example .env

# Edit with your credentials
nano .env

Your .env file can contain:

# Required
CLOUDFLARE_API_TOKEN=your_cloudflare_api_token_here

# Optional (can also be passed as CLI arguments)
DOMAIN=example.com
EMAIL=admin@example.com

# Optional settings
STAGING=0                    # Set to 1 for staging/test certificates
PROPAGATION_SECONDS=10       # DNS propagation wait time

Security Note: The .env file is already in .gitignore. Never commit API tokens to version control.

Usage

Three Ways to Use This Tool

1. Using .env File Only

Set everything in .env and run without arguments:

# .env file contains: CLOUDFLARE_API_TOKEN, DOMAIN, EMAIL
cloudflare-request-cert

2. Using Command-Line Arguments Only

# Provide all parameters via CLI (API token still from .env or environment)
cloudflare-request-cert -d example.com -e admin@example.com
# Store sensitive data in .env, pass domain/email via CLI
# This is useful when managing multiple domains
cloudflare-request-cert -d example.com -e admin@example.com

Using Make Commands

Request a certificate with Make:

# Basic usage
make run DOMAIN=example.com EMAIL=admin@example.com

# Test with staging first (recommended)
make run DOMAIN=example.com EMAIL=admin@example.com STAGING=1

Advanced Options

# Custom DNS propagation time
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --propagation-seconds 30

# Use staging environment for testing
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --staging

# Use custom .env file
cloudflare-request-cert \
  -d example.com \
  -e admin@example.com \
  --env-file /path/to/custom.env

Priority Order

When the same setting is provided in multiple places, this is the priority order (highest to lowest):

  1. Command-line arguments (highest priority)
  2. .env file
  3. Environment variables (lowest priority)

Example:

# .env has DOMAIN=old.com
# This will use new.com (CLI argument takes precedence)
cloudflare-request-cert -d new.com -e admin@example.com

Makefile Commands

Command Description
make help Show all available commands
make venv Create virtual environment
make install Install uv and sync dependencies (alias for venv)
make sync Sync dependencies with uv
make dev Install development dependencies
make run Run the certificate request tool
make lint Lint code with ruff
make format Format code with ruff
make check Run all checks (lint + format)
make test Run tests
make sbom Generate SBOM (Software Bill of Materials)
make clean Remove virtual environment and cache

Certificate Locations

After successful certificate generation, your certificates will be stored at:

/etc/letsencrypt/live/your-domain.com/
├── cert.pem       # Your certificate
├── chain.pem      # The certificate chain
├── fullchain.pem  # cert.pem + chain.pem
└── privkey.pem    # Your private key

DNS Propagation Time

The tool waits for DNS changes to propagate before Let's Encrypt validates your domain. Default is 10 seconds, but you can adjust this:

# Via CLI
cloudflare-request-cert -d example.com -e admin@example.com --propagation-seconds 30

# Via .env
PROPAGATION_SECONDS=30

Automatic Renewal

Certbot automatically handles renewal. Set up a cron job or systemd timer:

# Cron example (runs daily at 2 AM)
0 2 * * * certbot renew --quiet

# Or use systemd timer (recommended)
sudo systemctl enable --now certbot-renew.timer

Development

Install Development Dependencies

make dev

Run Tests

make test

Run Linting

make lint

Format Code

make format

Run All Checks

make check

Generate SBOM

Generate a Software Bill of Materials (SBOM) in CycloneDX JSON format:

make sbom

The SBOM will be saved to bom.json.

Example Workflows

First Time Setup

# 1. Install dependencies
make install

# 2. Set up configuration
cp .env.example .env
nano .env  # Add your Cloudflare API token

# 3. Test with staging (won't affect rate limits)
cloudflare-request-cert -d example.com -e admin@example.com --staging

# 4. Get production certificate
cloudflare-request-cert -d example.com -e admin@example.com

Managing Multiple Domains

# Store API token in .env
echo "CLOUDFLARE_API_TOKEN=your_token" > .env

# Request certificates for different domains
cloudflare-request-cert -d site1.com -e admin@site1.com
cloudflare-request-cert -d site2.com -e admin@site2.com
cloudflare-request-cert -d site3.com -e admin@site3.com

Automated Script

#!/bin/bash
# renew-certs.sh

DOMAINS=("site1.com" "site2.com" "site3.com")
EMAIL="admin@example.com"

for domain in "${DOMAINS[@]}"; do
    echo "Requesting certificate for $domain..."
    cloudflare-request-cert -d "$domain" -e "$EMAIL"
done

Troubleshooting

"certbot not found"

Install certbot and the Cloudflare plugin:

make install
# or
uv sync

"CLOUDFLARE_API_TOKEN is required"

Make sure your .env file exists and contains:

CLOUDFLARE_API_TOKEN=your_actual_token_here

"DOMAIN is required" or "EMAIL is required"

Either set them in .env:

DOMAIN=example.com
EMAIL=admin@example.com

Or pass them as arguments:

cloudflare-request-cert -d example.com -e admin@example.com

API Token Permissions

Ensure your Cloudflare API token has:

  • Zone:DNS:Edit permissions
  • Zone:Zone:Read permissions

DNS Propagation Issues

If validation fails, try increasing propagation time:

cloudflare-request-cert -d example.com -e admin@example.com --propagation-seconds 60

Or set in .env:

PROPAGATION_SECONDS=60

Rate Limits

Let's Encrypt has rate limits. Use staging for testing:

# Set in .env
STAGING=1

# Or via CLI
cloudflare-request-cert -d example.com -e admin@example.com --staging

Comparison with Original

This is a Cloudflare remake of the loopia-request-cert tool with several improvements:

  • Uses Cloudflare instead of Loopia DNS
  • Uses uv for faster dependency management (10-100x faster than pip)
  • Modern pyproject.toml configuration
  • Improved Makefile with more commands
  • Better error handling and user feedback
  • Flexible configuration: .env file, CLI args, or both
  • Type hints for better code quality
  • Ruff for linting and formatting
  • Comprehensive tests

License

MIT License

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Resources

Metadata

Release files for cloudflare-request-cert 0.1.20

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cloudflare-request-cert 0.1.20
File Size Uploaded Provenance Actions
cloudflare_request_cert-0.1.20.tar.gz 99.6 kB With provenance Details for cloudflare_request_cert-0.1.20.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cloudflare-request-cert 0.1.20
File Interpreter ABI Platform Actions
cloudflare_request_cert-0.1.20-py3-none-any.whl Python 3 none any Details for cloudflare_request_cert-0.1.20-py3-none-any.whl

Total release size: 108.6 kB

Release files / cloudflare_request_cert-0.1.20.tar.gz

Download URL cloudflare_request_cert-0.1.20.tar.gz
Size 99.6 kB
Tags Source
SHA-256 checksum
How to use checksums
609a6dd94de1bd81bf7f78d3537de63f9a8c8001cdfdb006ca94ff59823dfaee
BLAKE2b-256 checksum
How to use checksums
b0d37a6c0bbfdf8203d08fd37fbceba08f791c26957a082ab8c8f7fea57d15b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / cloudflare_request_cert-0.1.20-py3-none-any.whl

Download URL cloudflare_request_cert-0.1.20-py3-none-any.whl
Size 8.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c116212d8bb04340214d9cf3aeb2d729ded81b1ae5e24b44ceb0616805ec5326
BLAKE2b-256 checksum
How to use checksums
1bca02ac65f49dc6d822bab99a9219661b72f5a70dcb715d0edd1f9d0705d144
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Security for cloudflare-request-cert 0.1.20

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cloudflare_request_cert-0.1.20.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page