Mutual TLS (mTLS) with FastAPI and Uvicorn

The Challenge:

  • Help others who may want to configure mTLS with FastAPI
  • Clarify some of the lacking documentation (or things people know but may not have explained)
  • Document the approach (here)

The Approach

We Need two CAs:

  • A public CA (trusted) to create a secure channel
  • A validation CA which can issue client certs to be validated
  • A validation CA can be based on a public CA (however issuing client certs may be expensive) and Internal CA Based on Something Like Active Directory or a Self Manage CA.
  • I am going to use a Self Managed CA.

Nuts and Bolts

  • Create a validation_fullachain.pem for your validation CA. Below is my fullchain which has the Cryptoroo Root CA and the FastAPI MTLS Proofs Intermediate.
  • Create a Leaf Certificate Signed by the FastAPI MTLS Proofs Intermediate. Note: usually the Common Name is all that is needed for a MTLS Client Cert but you can add other extensions (e.g. OU, etc). Make sure that you add the Client Authentication Extended key usage.

Testing and Implementing

Phase 1: Ensure TLS/SSL is working

  • Run the command below. This should be the path to your Public CA Certificates.
  • For Let’s Encrypt it is the fullchain.pem and the privkey.pem files. Note: I use windows but linux clients should be /live/{domain}/ as well.
  • Note: I am using port 443 for a specific reason to make the testing consistent.
  • Note: You will need to run this as administrator on windows in order to be able to open the Certbot certificates.
uvicorn main:app — ssl-certfile <fullchain certificate in PEM> — ssl-keyfile <RSA / ECC Private Key>  — port 443
  • Browse to your domain name (mine is fastapi-mtls.cryptoroo.xyz) and inspect the certificate. If you see Let’s Encrypt and a green padlock you are good to go to the next phase.

Phase 2: For Testing CERT_OPTIONAL Configuration

  • Review the functioning of the CERT_OPTIONAL flag here. https://docs.python.org/3/library/ssl.html#ssl.CERT_OPTIONAL
  • Essentially the browser will ask for a certificate but if one is not presented it will allow users through.
  • Note: I can’t seem to be able to get the browser to show my self signed certificate so in the next phase I will use Postman and OpenSSL for verification
uvicorn main:app 
— ssl-certfile <fullchain certificate in PEM> — ssl-keyfile <RSA / ECC Private Key>
ssl-cert-reqs 1 --ssl-ca-certs <fullchain certificates in PEM>
— port 443

Browser Asking for a Certificate.

Clicking Cancel

  • Not sending a certificate still allows you to use the service.

Phase 3: For Testing CERT_REQUIRED Configuration

uvicorn main:app 
— ssl-certfile C:\Certbot\live\cryptoroo.xyz\fullchain.pem — ssl-keyfile C:\Certbot\live\cryptoroo.xyz\privkey.pem
— ssl-cert-reqs 2 — ssl-ca-certs E:\GITHUB\cryptoroo_ca\complete.crt
— port 443

Postman Call with no Client Cert:

Configuring Postman to Use SSL Certificates for https://fastapi-mtls.cryptoroo.xyz/docs

Refer to here for more details: https://learning.postman.com/docs/sending-requests/certificates/

Success!!:

Verify that the certificate is in fact passed in:

Testing With OpenSSL:

openssl s_client -connect fastapi-mtls.cryptoroo.xyz:443 -cert <path to your mtls cert> -key <path to your mtls key>

We then Should get a command Prompt at the bottom:

Type In the Following to test a GET to the Root (/)

GET / HTTP/1.1
Host: fastapi-mtls.cryptoroo.xyz

Summary:

  • mTLS is quite possible and easy to configure with FastAPI
  • Uvicorn provides some tips on how to set this up but it does require knowledge of Python TLS/SSL library
  • There is an assumed knowledge of TLS and which arguments perform which function
  • Testing in Browser is hard as the personal keys don’t show up

To Do:

  • Demo using CURL
  • Fix Browser SSL Certificate Issue
  • Video Demos
  • Demo of how to create a Validation CA

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

I hate P@55w0rd policy and security questions

eMAPT Certification Exam Review

https%3A%2F%2Felearnsecurity.com%2Fproduct%2Femapt-certification%2F&psig=AOvVaw0_xne9If_H4AvPX0c2qW5g&ust=1652367993707000&source=images&cd=vfe&ved=0CAwQjRxqFwoTCIiM6vXc1_cCFQAAAAAdAAAAABAD

{UPDATE} One Night Chinese Hack Free Resources Generator

Wi-Fi Security — Are You at Risk?

Russia APT

What the Heck is Threat Intelligence?

MITRE PRE-ATT&CK

{UPDATE} Fire-Ball Proshot Defender Arcade Free Games Hack Free Resources Generator

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andrei Hawke

Andrei Hawke

More from Medium

Deploy a containerised fastapi APP in minikube

Python: Flask Development on Kubernetes with DevSpace

Building Docker images that require NVIDIA runtime environment

Building scalable SOAR infrastructure