You’ve seen the error. You’ve felt the panic.
SSLError(CertificateError("hostname 'bankofamerica.com' doesn't match..."))
And you’ve probably done the “lazy fix”: adding verify=False just to make the red text go away.
Stop.
Before you disable security on your production app, let’s actually understand what verify and cert do. And because SSL handshakes are boring, we’re going to visualize them as a high-stakes money transfer.
The Analogy: The Armored Courier
Imagine requests is an Armored Courier (Client).
The server (e.g., google.com) is the Bank (Server).
The payload is a Bag of Cash (Data).
There are two critical questions that must be answered before any money changes hands:
- “Is this the Real Bank?” (Handled by
verify) - “Is this a Real Courier?” (Handled by
cert)
1. verify: Checking the Bank
Who checks who? The Courier checks the Bank.
Default in Requests: True (Secure).
When you send a request, your code wants to know if it’s talking to the real server or an imposter.
The Mechanism
- Bank presents its ID Card (SSL Certificate).
- Courier checks its Book of Trusted IDs (CA Bundle).
- If the Bank’s ID is signed by someone in the Book? Trust.
Interactive Simulation: The Trust Check
Scenario A: verify=True (The Good)
By default, requests acts like a strict bouncer. It grabs the digital ID bundle from certifi (a Python package containing trusted CAs like DigiCert, Let’s Encrypt).
| |
Scenario B: verify=False (The Ugly)
You turn off the ID check. The courier walks up to anyone wearing a “Bank” t-shirt and hands them the money.
This is fine for localhost testing.
This is suicide on public WiFi or the open internet.
| |
Pro Tip: If you have a custom internal CA (common in corporate VPNs), don’t set False! Instead, point to your company’s certificate file:
requests.get(url, verify='/path/to/company-ca.pem')
2. cert: The Badge Check
Who checks who? The Bank checks the Courier.
Also known as: mTLS (Mutual TLS) or Two-Way SSL.
Sometimes, the Bank is exclusive. It doesn’t talk to just anyone. It demands proof that you are an authorized courier.
The Mechanism
- Courier initiates connection.
- Bank says “Show me your badge.”
- Courier sends its Client Certificate (
.crt) and Private Key (.key). - Bank validates the badge. If valid? Access Granted.
Interactive Simulation: The Double Check
How to use it
You need two files from your security team: a Certificate (public ID) and a Key (secret password).
| |
Sometimes these are combined into a single .pem file. In that case, just pass the string path:
cert='/path/to/combined.pem'.
TL;DR Summary
| Parameter | Analogy | Who is being checked? | Why use it? |
|---|---|---|---|
verify | The ID Check | The Server | To ensure you aren’t sending data to a hacker. |
cert | The Badge | The Client (You) | To prove you have permission to access the server. |
Next time requests throws an SSL error, don’t just blindly set verify=False. Ask yourself: Do I trust this bank?
