Isbister
Isbister

Reputation: 946

Authenticating service-to-service on GCP fails from local machine

I am trying to authenticate, however the requests library in python3 does not let me fetch the token. Using the following code example: https://cloud.google.com/run/docs/authenticating/service-to-service#python

# Requests is already installed, no need to add it to requirements.txt
import requests

receiving_service_url = "https://myproject....run.app"

# Set up metadata server request
# See https://cloud.google.com/compute/docs/instances/verifying-instance-identity#request_signature
metadata_server_token_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience='

token_request_url = metadata_server_token_url + receiving_service_url
token_request_headers = {'Metadata-Flavor': 'Google'}

# Fetch the token
### CRASHES HERE ###
token_response = requests.get(token_request_url, headers=token_request_headers) ###
### CRASHES HERE ###
jwt = token_response.content.decode("utf-8")

# Provide the token in the request to the receiving service
receiving_service_headers = {'Authorization': f'bearer {jwt}'}
service_response = requests.get(receiving_service_url, headers=receiving_service_headers)

print(service_response.content)

If i run the same code inside the Console in gcp, with iPython, it can fetch the token. And I can use it from my local machine with e.g CURL.

Error:

token_response = requests.get(token_request_url, headers=token_request_headers)
  File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 76, in get
    return request('get', url, params=params, **kwargs)
  File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "/Users/tim/anaconda3/envs/sklearn/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='metadata', port=80): Max retries exceeded with url: /computeMetadata/v1/instance/service-accounts/default/identity?audience=https://myproject....run.app (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f87f0573370>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))
INFO:werkzeug:127.0.0.1 - - [08/Oct/2020 23:54:14] "GET / HTTP/1.1" 200 -

Why cant I establish a connection when running this on my local machine?

Upvotes: 1

Views: 938

Answers (1)

guillaume blaquiere
guillaume blaquiere

Reputation: 76010

If you base your code on metadata server, it will works only on Google Cloud. I answered this question yesterday, and I think, you can get inspiration from it.

Instead of using the metadata server, you can use the IAM rest API to generateIDToken. Like this, it works locally and in the cloud.

The code is a bit longer, and I don't know if the IAM API is as efficient as metadata servers.

If you need details and explanation, don't hesitate to comment!

Upvotes: 1

Related Questions