Lazy instantiation of ssl_context in a Client or Transport #1374
Labels
discussion
tls+pki
Issues and PRs related to TLS and PKI
user-experience
Ensuring that users have a good experience using the library
Checklist
This topic probably touches on -
Is your feature related to a problem? Please describe.
In some situations, we need to prompt a user for a password just prior to creating an
ssl.SSLContext
. For instance, if a user has password-protected PKCS12 certificates, we usepypki2
orrequests_pkcs12
to decrypt the certificate and build anssl.SSLContext
. While I do not have an example on hand for HSM (Hardware Security Module, PKCS11 format, "Smart Cards" for example), these will probably fit into the same use case.Normally, the flow in something like a Jupyter Notebook would not be a problem -
context = pypki2config.ssl_context()
-> prompts for password ->client = httpx.Client(verify=context)
. The wrinkle is that we have a development environment where some domains require a PKI (PKCS12) authenticated request, while others don't. I'll call them a list ofaudited
domains andclear
domains.The behavior I want is for a user to create a
client = InternalClient()
object, a subclass ofhttpx.Client
that knows about which domains need a PKI-sourcedssl_context
and which need a barehttpx.create_ssl_context()
. I would like to lazily instantiate those contexts so that there is no password prompt atclient
init, and may never be a password prompt if the user does not make a request to anaudited
domain.Our solution right now is to use a subclassed
requests.Session
object,session = InternalSession()
. We override.send
(although.get_adapter
could have worked too) to create/mount the right adapter at the time of the request.Describe the solution you would like.
There are probably many ways to make our use-case work. Here are some options that come to mind -
client.mount
method (@tomchristie was against this in 977), which we would invoke while overriding.send
or somethingmounts
dictionary values be aTransport
or a callback that returns aTransport
at the time the Transport is needed.get_transport(url)
method that can be overridden (ala.get_adapter
in requests). The default behavior would be to perform URL matching from the.get_transports()
dictionaryhttpcore.Transport
ssl_context
init variable to accept a callback, and that callback wouldn't be executed until needed (such as when._open_socket
is invoked)Thanks so much!
The text was updated successfully, but these errors were encountered: