1
votes

Using service account credentials of the GCP project I want to access the Google 'My drive' of the Google workspace account without pre-authorising the folder.

I am successfully able to authorize and access the folder that have been shared with the service account but I want to access the 'My Drive' of all the GWS account in the same Domain.

Is there a way to do so?

2

2 Answers

0
votes

Yes, that is actually possible.

You need to:

  1. Create the project/service account/get the service account credentials (.json key)
  2. Enable Domain Wide Delegation in the Google Workspace Admin console by adding the client ID + the scopes required.
  3. In your code, you need to make sure to impersonate the accounts (in your Google Workspace domain), you want to access.

Below is a sample code on how to do so using python (but the idea is the same in every language):

from __future__ import print_function
from googleapiclient.discovery import build
from google.oauth2 import credentials, service_account

# Scopes required by this endpoint -> https://developers.google.com/drive/api/v3/reference/files/get
SCOPES = ["https://www.googleapis.com/auth/drive"]

# Service Account Credentials to be used. How to create at https://developers.google.com/workspace/guides/create-credentials#service-account
SERVICE_ACCOUNT_FILE = 'YourServiceAccountCredentials.json'
credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes= SCOPES)
delegated_creds = credentials.with_subject("[email protected]")

service = build('drive', 'v3', credentials = delegated_creds)

results = service.files().list(orderBy = 'name', pageSize = 100, corpora= 'user').execute()
items = results.get('files', [])

if not items:
    print("no files found")
else:
    print("Document name + FileID ")
    for item in items:
        print(u'{0} ({1})'.format(item['name'], item['id']))
0
votes

There are two ways to grant a service account access to someone's google drive account.

The first and easiest is to simply share a folder with the Service account. This will act just like it would if you shared the folder with anyone else. They would get access to it. The draw back to this method is that you can only share a folder. You cant for example share a root folder the of the users Google drive account.

In the case of google workspace there is a second option.

THe admin of the Google workspace domain can set up something called domain wide deligation for the service account. By setting up domain wide delegation you are giving the service account the ability to impersonate or pretend to be the actual user of that account.

So in the case of the code below. The service object is created and we tell it which user we are going to impersonate this being gsuiteUser.

 var certificate = new X509Certificate2(@"D:\creds.p12", "notasecret", X509KeyStorageFlags.Exportable);

 var gsuiteUser = "[email protected]";

 var service = new ServiceAccountCredential.Initializer(serviceAccount)
        {
            User = gsuiteUser,
            Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }

        }.FromCertificate(certificate);

So as far as google drive api is concerned all requests that come from my service object are coming from gsuiteUser which means that i can see everything that this user can see including the root directory.

You should set up domain wide delegation and have your code impersonate each of the users on your domain. Or create a separate user with access to everything and let the service account access that single user.