googleapis / google-auth-library-python

Google Auth Python Library
https://googleapis.dev/python/google-auth/latest/
Apache License 2.0
772 stars 305 forks source link

google.oauth2.service_account.Credential objects are not pickleable if cryptography is installed #1383

Closed andrewsg closed 11 months ago

andrewsg commented 12 months ago

Environment details

Steps to reproduce

Install cryptography

Run:

import pickle
from google.oauth2 import service_account

credentials = service_account.Credentials.from_service_account_file("credentials.json")

pickle.dumps(credentials)

The object in question seems to be credentials._signer which is either a pickleable pure Python object if cryptography is not installed, or else an unpickleable google.auth.crypt._cryptography_rsa.RSASigner if it is. Specifically, the signer._key object is of type cryptography.hazmat.backends.openssl.rsa._RSAPrivateKey.

This conversation on SO seems related: https://stackoverflow.com/questions/39321606/cant-pickle-an-rsa-key-to-send-over-a-socket

This is impacting the Storage SDK's multiprocessing capability: https://github.com/googleapis/python-storage/issues/1116 despite efforts to work around it.

clundin25 commented 11 months ago

I'm not sure how this should be implemented.. Any object that is pickled would need to reconstruct the signer object to work, which requires the key's PEM file. Put another way, it seems to me that the the object needs to be recreated each time.

@arithmetic1728 @sai-sunder-s what do you think?

The base OAuth2.0 credential object does support pickling https://github.com/googleapis/google-auth-library-python/blob/main/google/oauth2/credentials.py#L156.

clundin25 commented 11 months ago

Maybe we could store a buffer of the key's bytes, and then recreate the signer that way?

arithmetic1728 commented 11 months ago

@clundin25 yes I think we could store the key bytes and recreate the signer