I am trying to create a Google service account to make user account changes in our Google Workspace instance. I have followed the instructions on the page "Perform Google Workspace Domain-Wide Delegation of Authority". That is, I have
Created a service account in our Google Cloud Project.
Created a key for that service account and downloaded the JSON string version of that key.
Added the service account to "Security > API Controls > Domain-wide Delegation" in the admin panel for our instance.
Added the scope https://www.googleapis.com/auth/admin.directory.user
to that service account in the Domain-wide Delegation section.
The code I am running is this:
import os.path
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from google.oauth2 import service_account
SCOPES = ['https://www.googleapis.com/auth/admin.directory.user']
def main():
creds = service_account.Credentials.from_service_account_file(
'credentials.json', scopes=SCOPES)
service = build('admin', 'directory_v1', credentials=creds)
results = service.users().list(customer='my_customer', maxResults=10,
orderBy='email').execute()
users = results.get('users', [])
if not users:
print('No users in the domain.')
else:
print('Users:')
for user in users:
print(u'{0} ({1})'.format(user['primaryEmail'],
user['name']['fullName']))
if __name__ == '__main__':
main()
The file credentials.json
(after some redacting) looks like this:
{
"type": "service_account",
"project_id": "myproject-uat1",
"private_key_id": "f19f6e738923406283302659fbdde8abdsbeb2fd",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvg...Wo\n-----END PRIVATE KEY-----\n",
"client_email": "myproject-uat-a@myproject-uat1.iam.gserviceaccount.com",
"client_id": "116674234874240871478",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/myproject-uat-a%40myproject-uat1.iam.gserviceaccount.com"
}
When I run the above I get this result:
Traceback (most recent call last):
File "/root/test.py", line 31, in <module>
main()
File "/root/test.py", line 17, in main
results = service.users().list(customer='my_customer', maxResults=10,
File "/usr/local/lib/python3.9/dist-packages/googleapiclient/_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python3.9/dist-packages/googleapiclient/http.py", line 938, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer&maxResults=10&orderBy=email&alt=json returned "Invalid Input". Details: "[{'message': 'Invalid Input', 'domain': 'global', 'reason': 'invalid'}]">
This question is similar to this StackOverflow question but the answers to that question, unfortunately, did not help me.
I think you need to use create_delegated
to create credentials (using the Service Account) delegated to operate on behalf of an admin user that is permitted to use the Workspace Admin APIs.
See: example