0
votes

I am trying to convert the following command from CLI (that works) to python but I am having some problems.

curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" SERVICE_URL

The problem is that I cannot request a valid Bearer with application default local credentials token to make authorized request to Google Cloud Run. If I generate Bearer token from CLI gcloud auth print-identity-token and use it in a python request all works fine

request_url = 'https://<my endpoint>'
identity_token = '<>' # response of gcloud auth print-identity-token)
header= {'Authorization': f'Bearer {identity_token}'}
requests.get(url=request_url, headers=receiving_service_headers)

From google auth documentation I understood that Cloud Run communicationis based on Identity Tokens that support Impersonated authentication but I cannot generate valid credential.

from google.auth import impersonated_credentials, default
from google.auth.transport.requests import AuthorizedSession

request_url = 'https://<my endpoint>'
source_credentials, project = default()

creds = impersonated_credentials.IDTokenCredentials(
    source_credentials,
    target_audience=request_url)

authed_session = AuthorizedSession(creds)
resp = authed_session.get(request_url)
print(resp)

bui I get following error

google.auth.exceptions.GoogleAuthError: Provided Credential must be impersonated_credentials

Thanks

2
Edit your question with a minimum reproducible example. For example, you are not showing how you are creating credentials (source_credentials). Do you actually need to impersonate? What are you impersonating?John Hanley
The second snippet of code can be used to reproduce the error. I get local application default creds with default() method (after executing gcloud auth application-default) rhen I need to get from this creds identity token to make a call on an authorized cloud run endpoint. I don't think I need impersonate but I found this solution as a workaround to use application default credential since source_credential.id_token gives unauthorized. If i use service_account.IDTokenCredentials.from_service_account_file works correctly.Paolo Fusari

2 Answers

0
votes

Please follow the enter link if you want to convert the curl command to python request. Here is converted code:

import requests

headers = { 'Authorization': 'Bearer $(gcloud auth print-identity-token)', }

response = requests.get('http://SERVICE_URL', headers=headers)

0
votes

Today it's impossible. I talked about it in an article. You need a service account to generate a valid JWT token with the Google Auth library. It's the same problem with all the library and all the languages.

Last week, I pushed a merge request in the Java auth library to solve this. I don't know why Google don't implement it by itself.

On your local environment, if you want to use the same code locally and in the cloud, you have to generate a service account key file and use it with ADC. And it's sadly a security issue...