0

I'm trying to automate creating Firewall Rules for my Python 3 Google App Engine. Per their docs, I can use the Admin API for that (which I've enabled in the Cloud Console). I've created an API Key too on the APIs & Keys/Credentials page (no restrictions). The Python library implies I can use this key with that library. However, When I use my API_KEY with the below code, I get:

googleapiclient.errors.HttpError: <HttpError 401 when requesting https://appengine.googleapis.com/v1beta/apps/{my project ID}/firewall/ingressRules?key={my API Key}&alt=json returned "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.". Details: "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.">

The URLs in the error are useless because I'm deliberately trying not to use Oauth2 (overkill). Here's the code producing the above error:

from googleapiclient.discovery import build


def set_firewall_rules(file_name):
    infile = open(file_name)
    service = build('appengine', 'v1beta', developerKey=API_KEY)
    existing_rules = service.apps().firewall().ingressRules().list(appsId='{my project ID')
    print(existing_rules.execute())
    service.close()
    return

Why is my API key insufficient? Are there settings on my app I need to change, or do I have to make a service account with scopes and all that Oauth2 stuff?

Also, I notice that if if I move my service.close() line before my print line, I get AttributeError: 'Http' object has no attribute 'http', so it seems I'm at least 2 steps away from success. It makes using gcloud in a bash script the easier way to go...

I'm using Python 3.8 in a virtual env with google-api-python-client 1.12.8.

hamx0r
  • 4,081
  • 1
  • 33
  • 46

1 Answers1

0

Unfortunately it's not possible to use API key when calling apps.firewall.ingressRules.list. You need to use OAuth as the method requires the following OAuth Scopes:

  • appengine.admin
  • cloud-platform
  • cloud-platform.read-only

Here is a good answer with regards to authenticating with service account credentials. To note:

Notice the scopes parameter. This defines permissions that are granted to the resulting credentials object.

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = 'service-account-credentials.json'

from google.oauth2 import service_account

cred = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

As additional reference, here's the REST API:

https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1beta/apps.firewall.ingressRules/list

Here's the RPC equivalent:

https://cloud.google.com/appengine/docs/admin-api/reference/rpc/google.appengine.v1beta#firewall

Donnald Cucharo
  • 3,866
  • 1
  • 10
  • 17