googleapis / google-auth-library-python

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

Support/RFC/FR: safely print/compare access tokens for debugging purposes #1521

Closed pataquets closed 1 month ago

pataquets commented 2 months ago

I find myself having to debug auth-related code from time to time in several services. Sometimes I need to check if a token has changed or compare whether an object is using same token as somewhere else. And I need to do this outside my local development environment. Obviously, printing a token is a big no-no.

As far as I know there is no safe way to do this with the libraries' built-in functions. Is there?

What I'm currently doing is creating a SHA256 hash of the token to prevent its use and base64-encode the result for readability and compactness before printing it. AFAICT, there is no security risk in doing this. Also, I'm not aware of any existing method/function specifically for this. Is there?

Anyone knows a more idiomatic/terse/compact method to accomplish this? Would such a helper feature/function be an acceptable contribution?

arithmetic1728 commented 1 month ago

I don't think we have a simple way to do so, and this is not likely a feature we will support due to potential security concerns.

I have some ideas which might be helpful: each credential class in this lib has its own refresh method, e.g. https://github.com/googleapis/google-auth-library-python/blob/main/google/oauth2/service_account.py#L426, https://github.com/googleapis/google-auth-library-python/blob/main/google/oauth2/credentials.py#L376, etc. For the credential class you use, you can create a new class to inherit it, then override the refresh method to print out the encoded token hash.

class MyServiceAccountCredentials(google.oauth2.service_account.Credentials):
    def refresh(self, request):
        super().refresh(request)
        print(my_encoded_hash_method(self.token))

# create the credential
cred = MyServiceAccountCredentials.from_service_account_file('/path/to/JSON/file')

# pass cred to client
client = some_client(credentials=cred)
clundin25 commented 1 month ago

Closing this as stale. Please re-open should you have further questions.

Thanks!