Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud Run: Calling from outside GCP

I'm trying to access a secure cloud run service. If I try from my machine with the SDK it works fine:

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

However, I can not get it to work using the Python API using the same service account, I've tried using google-auth to get an access token but that gives me a 401 authentication error. This is the code I am using to try to get a token:

import google.auth
import google.auth.transport.requests

scopes = ['https://www.googleapis.com/auth/cloud-platform']

creds, projects = google.auth.default(scopes=scopes)
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

# then using creds.token 

Looking at the docs: https://cloud.google.com/run/docs/authenticating/service-to-service#calling_from_outside_gcp it says to follow the sample code here: https://cloud.google.com/iap/docs/authentication-howto#iap_make_request-python I can't seem to follow the guide as it says to enable IAP but it seems that IAP is only for app engine and not cloud run?

Has anyone go any advice on this one?

Thanks

like image 863
Dan Avatar asked Sep 18 '25 15:09

Dan


2 Answers

OK it seems that there is an IDTokenCredentials class that works for this as it uses Open ID Connect ID Tokens instead of OAuth 2.0 Access Tokens:

https://google-auth.readthedocs.io/en/latest/reference/google.oauth2.service_account.html

from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession

service_url = 'example.com'
key_file = 'key.json'

credentials = service_account.IDTokenCredentials.from_service_account_file(
    key_file, target_audience=service_url)
authed_session = AuthorizedSession(credentials)
response = authed_session.get(service_url)

It's confusing as I don't see it in the docs and it's leading me to something else about IAP which I don't think is working with Cloud Run.

like image 126
Dan Avatar answered Sep 21 '25 05:09

Dan


If you still want to obtain your ID token and not use method from Dan's response there is an updated code:

import requests
import google.auth    
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession

service_url = 'example.com'
key_file = 'key.json'

credentials = service_account.IDTokenCredentials.from_service_account_file(
    key_file, target_audience=service_url)
request = google.auth.transport.requests.Request()
credentials.refresh(request)
token = credentials.token
print('ID Token:', token)
like image 31
Pascal ddg Avatar answered Sep 21 '25 05:09

Pascal ddg