Skip to main content

Easy CA certificate management for Python and curl

Project description

cert-trust

PyPI version CI License: MIT

Easy CA certificate management for Python and curl.

Introduction

If you work in a corporate environment, you've probably seen this error:

curl: (60) SSL certificate problem: unable to get local issuer certificate
requests.exceptions.SSLError: certificate verify failed

This happens when your company's firewall intercepts HTTPS traffic using a custom CA certificate. Instead of disabling SSL verification (insecure!) or manually configuring every tool, cert-trust handles it for you.

One command fixes Python requests, urllib3, httpx, and curl. No code changes needed.

Installation

pip install cert-trust[all]

Requires Python 3.10 or later.

Quick Start

Enable system CA certificates:

cert-trust enable

Check if it's working:

cert-trust status

Add your company's CA certificate:

cert-trust add /path/to/company-ca.crt

Test an HTTPS connection:

cert-trust verify https://internal.company.com

Disable when not needed:

cert-trust disable

How It Works

Python: Installs a .pth file that automatically runs at Python startup. This injects system CA certificates into the SSL context. Works with requests, urllib3, httpx, and any library using Python's ssl module.

curl: Adds certificates to your OS certificate store.

Platform Method Admin Required
Windows User Certificate Store No
macOS User login keychain No
Linux System CA directories Yes (sudo)

On Linux, you'll need sudo to modify system-wide certificate stores.

Commands

enable - Enable system CA trust for Python

cert-trust enable

disable - Disable system CA trust

cert-trust disable

status - Show current status

cert-trust status          # Pretty output
cert-trust status -v       # Verbose
cert-trust status --json   # JSON output

add - Add a CA certificate

cert-trust add corporate-ca.crt

Supports .crt, .pem, .cer files

verify - Test HTTPS connection

cert-trust verify https://example.com

Python API

import cert_trust

cert_trust.enable()
cert_trust.status()
cert_trust.add_cert('/path/to/ca.crt')
cert_trust.verify('https://example.com')
cert_trust.disable()

Troubleshooting

Python still getting SSL errors? Restart your Python session. The .pth file only loads at startup.

curl errors on Windows? Make sure you're using the native curl.exe, not WSL or Git Bash curl.

Permission errors on Linux? Use sudo when running cert-trust add for curl support.

Environment Variables

Set CERT_TRUST_DISABLED=1 to temporarily disable without uninstalling:

export CERT_TRUST_DISABLED=1
python your_script.py

Development

git clone https://github.com/chuongmep/cert-trust.git
cd cert-trust
pip install -e ".[all,dev]"
pytest

License

MIT

Step Action
Python .pth Runs enable if not already active
Python certifi Appends the cert to the certifi bundle so requests picks it up immediately
curl — Linux (Debian/Ubuntu) Copies to /usr/local/share/ca-certificates/, runs update-ca-certificates
curl — Linux (RHEL/Fedora) Copies to /etc/pki/ca-trust/source/anchors/, runs update-ca-trust extract
curl — macOS Adds to System Keychain via security add-trusted-cert
curl — Windows Runs certutil -addstore -f ROOT <cert> → Windows Certificate Store

verify <url>

Test that a URL is trusted by both curl and Python's ssl module after adding your cert.

cert-trust verify https://internal.corp.example.com
cert-trust verify https://internal.corp.example.com --json

Temporary disable (without uninstalling)

Set the CERT_TRUST_DISABLED environment variable to skip injection for a single process:

# Linux / macOS
CERT_TRUST_DISABLED=1 python my_script.py

# Windows (PowerShell)
$env:CERT_TRUST_DISABLED=1; python my_script.py

# Windows (Command Prompt)
set CERT_TRUST_DISABLED=1 && python my_script.py

How it works

cert-trust enable
      │
      ▼
cert_trust_bootstrap.pth   ← written to site-packages
      │
      │  Python reads all .pth files at interpreter startup
      ▼
cert_trust.bootstrap._inject()
      │
      ├─ truststore installed? → truststore.inject_into_ssl()   (cleanest)
      │
      └─ fallback → monkey-patch ssl.create_default_context
                    to call ctx.load_default_certs() on every new context

cert-trust disable simply deletes the .pth file — no other state is modified.


Platform support

Platform Python trust curl trust Requires elevated privileges?
Linux (Debian/Ubuntu) .pth + certifi update-ca-certificates sudo for curl
Linux (RHEL/Fedora) .pth + certifi update-ca-trust extract sudo for curl
macOS .pth + certifi System Keychain sudo for curl
Windows 10/11 .pth + certifi Windows Certificate Store (certutil) Run as administrator for curl

Windows target: CPython from python.org + the native curl.exe built into Windows 10 1803+. Native curl.exe uses WinSSL/Schannel and reads the Windows Certificate Store automatically after certutil imports the cert.

macOS note: curl installed via Homebrew (brew install curl) links against Homebrew's OpenSSL and does not read the System Keychain. In that case, pass the cert directly: curl --cacert /path/to/corp-ca.crt ...


Optional dependencies

Extra Package Effect
[rich] rich Coloured, formatted terminal output
[truststore] truststore Cleaner system cert injection (Python 3.10+)
[all] both Recommended
pip install "cert-trust[all]"

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cert_trust-1.0.0.tar.gz (19.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cert_trust-1.0.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file cert_trust-1.0.0.tar.gz.

File metadata

  • Download URL: cert_trust-1.0.0.tar.gz
  • Upload date:
  • Size: 19.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for cert_trust-1.0.0.tar.gz
Algorithm Hash digest
SHA256 6dfecd1d79ebda9968c35a5ab15efecaabcc981b646069d44f9aea00b5419823
MD5 4c1b63f71a976136da04acebfe5b3da3
BLAKE2b-256 293d529703daf40681e893fd3d7b4c62895a826755be8c18b8afa22d1434b3e3

See more details on using hashes here.

File details

Details for the file cert_trust-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: cert_trust-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for cert_trust-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 57857cde046e2048e4ff24e53bf374e55c5569c5e448d47dc22acf2860252e87
MD5 def71430ead0f49994aaed79bbe939e7
BLAKE2b-256 f439ddd891cb20f29b2b19d48d085b3b597e1a89caed3f57917bdb1d72ded624

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page