4

I'm trying to use the what Google terms a 'Domain-wide delegation' service account: https://developers.google.com/admin-sdk/directory/v1/guides/delegation

The specific API I'm trying to access with this delegation is: https://developers.google.com/apps-script/api/

Here's the code:

from google.oauth2 import service_account
import googleapiclient.discovery
import json
import os

SCOPES = ['https://www.googleapis.com/auth/script.projects', 'https://www.googleapis.com/auth/drive']
SERVICE_KEY = json.loads(os.environ['SERVICE_KEY'])

credentials = service_account.Credentials.from_service_account_info(SERVICE_KEY, scopes=SCOPES)
delegated_credentials = credentials.with_subject('fred.bloggs@my-gapps-domain.com')
script = googleapiclient.discovery.build('script', 'v1', credentials=delegated_credentials)

response = script.projects().get(scriptId='<myscriptId>').execute()
print json.dumps(response)

This fails with:

google.auth.exceptions.RefreshError: ('unauthorized_client: Client is unauthorized to retrieve access tokens using this method.', u'{\n  "error" : "unauthorized_client",\n  "error_description" : "Client is unauthorized to retrieve access tokens using this method."\n}')

I'm pretty sure I've followed all the steps at https://developers.google.com/api-client-library/python/auth/service-accounts, including authorizing the 'https://www.googleapis.com/auth/script.projects' scope with the client ID of the service account json key I downloaded.

enter image description here

Note, I was able to successfully get this particular snippet to work by skipping with_subject, and going in to the Script dashboard as the user, and 'sharing' the script project.

Unfortunately though that still doesn't allow upload a new set of files (as 'sharing' doesn't give the ability to delete). It does at least confirm my calling code is correct, albeit not authenticating properly with the json service key.

To clarify:

  • The script in question is what I believe is termed 'standalone' (not a web app)
  • It's owned by a bot user I've setup just like a regular GSuite user (as I didn't want scripts in regular user's Google Drives)
  • The script started in a Google Cloud Project that seemed to be automatically created, and with 'No organisation'. I then created a new project manually within the organisation, and moved the script to that project.

There's an official Google Apps Script client now, so I asked there too https://github.com/google/clasp/issues/225#issuecomment-400174500 - although they use the Javascript API (via Typescript), the principles should be the same.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
Marcos Scriven
  • 581
  • 1
  • 5
  • 15
  • Based from this [link](http://answerqueen.com/j7/d1nlpylpj7), Google API Service Account Authorization Error happens periodically. However, to impersonate an user, you must [grant the service account access](https://developers.google.com/api-client-library/php/auth/service-accounts#delegatingauthority). Also, this error intermittently happens when the account that's being impersonated is newly created. Try adding a 10 second delay before trying to create the service eliminates the problem. – abielita Jun 27 '18 at 15:40
  • @abielita - I tried a 10 second delay to no avail. The granting service account section is exactly the screenshot I showed. It's so frustrating how much of a black box this is. – Marcos Scriven Jun 29 '18 at 07:07

0 Answers0