I do a lot of work with SSL Certs. If you are using publicly trusted client certificates (i.e. LetsEncrypt, Digisign, etc), then you basically just need to do what Michael suggested - ensure your gateway or server populates the headers or environment variables with the information for the client. Most implementations for that stuff will also insert a secret-signed header field to ensure the client did not try and stuff headers themselves. You'd then need to validate the certificate again within python (see workaround #3 below)
I think this is going to be a bit of a headache if you are using untrusted CAs for the client certificates (ie. you control the CA and allocate the certs to your clients/partners) and trying to implement the sort of policy that PostgreSQL and other systems offer with client verification.
The complexity and level of work required come down to the following factors:
* Who will issue the client certificates (a public trusted CA or your own private CA)
* How much validation can you split between the gateway/server and Python (based on application design and business logic constraints), and where can the errors pop-up?
If you are talking about custom CA certs, the two approaches I know of for this sort of stuff:
1- (Easy for developer, harder for client) The client application stuffs the certificate into a header. Everything happens as normal Pyramid app. You just write pyramid code to require and validate the certificate header. This isn't actually mTLS, but uses the client certificate similar to ssl keychains.
2. (Hard for developer, easy for client) Actually use TLS Mutual Auth, which is what Theron first brought up. With mTLS, the client certificate is presented and validated during the TLS handshake - which means you would need to configure the gateway or mod_wsgi to handle the validation.
The large complexity of #2 is that many web servers / gateways can only be configured with a single client CA or a static client CA store - so building this as scalable to multiple clients may not necessarily be possible.
The three workarounds I can think of are:
1- Don't terminate TLS or validate the client certificate on the gateway, instead pass it all back to a python server like Waitress and see if you can handle everything via middleware to process the SSL connection.
2- Terminate TLS on OpenResty(nginx) and use a Lua script to handle the client validation. Then you can proxy that back to mod_wsgi. I opensourced our dynamic SSL certificate tool for OpenResty here -
https://github.com/aptise/lua-resty-peter_sslers - it does not do client certificates, but IMHO is a good reference for what you want to accomplish. it looks like OpenResty has some builtin stuff for this, but if not - those are the correct hooks.
3- Terminate TLS on the gateway but make it very lax for the client certificate to pass - basically just checking to see if the certificate is valid and from the CA. Then validate the client a second time in middleware/tween to ensure the certificate is active and allowed.