3
votes

Background

I have a google sheet, who's data I need to process on my local system. The nature of processing is very tedious and long so I wrote a script for it.

Problem

I need to access the google sheet through the python script to process it further. Online it is mentioned that to read the private google sheet directly, I need to create a GCP project and within that project, I need to create a service account. After that I should download the credentials and share the google sheet with that service account email.

Two problems here are :

  1. Downloading the credentials -- insecure and my organization prohibits it.
  2. Sharing of google sheet with service account email. organization also prohibits sharing sheet with outside organization emails.

What I found as a solution

I came across a solution of impersonating a service account but I could not find anything as to how can I do that. (Would appreciate any insights on that). All the other solutions suggested to download credentials which is a big NO.

For the sharing of sheets thing, I guess we can use drive API, but same problems are with that.

I tried using gcloud auth login and gcloud auth application-default login but was getting errors

Request had insufficient authentication scopes.". Details: "Insufficient Permission: Request had insufficient authentication scopes.

using ['https://www.googleapis.com/auth/spreadsheets', https://www.googleapis.com/auth/drive'] as scopes

What I need? (Summary)

How to access google sheets API (or download the Sheet from google drive) without downloading any sort of credentials.json.

2
Think about this from a security viewpoint. If your request were possible, what would stop the world from accessing the sheet? Your request is not possible with your limitations. You will need credentials. Either Google OAuth 2 User or Service Account. @DalmTo answer is correct.John Hanley
@JohnHanley The only restriction is to not download the credentials of the service account. The script can be used by multiple people in the organization and the credentials will have to be shared with each of them. Is there any way to authenticate without sharing the credentials, idk, maybe using something like gcloud auth login...Ojasv singh
gcloud auth login stores credentials on the local machine. The same type of credentials that you say your organization prohibits.John Hanley

2 Answers

1
votes

I assume you're looking at an example that looks a bit like this:

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow

SCOPES = ['https://www.googleapis.com/auth/spreadsheets',  
 'https://www.googleapis.com/auth/drive']

def main():
  flow = InstalledAppFlow.from_client_secrets_file(
    'credentials.json', SCOPES)
  creds = flow.run_local_server(port=0)

  drive_svc = build('drive', 'v3', credentials=creds)
  sheets_svc = build('sheets', 'v4', credentials=creds)

The library does it for you in two lines of code, but you can read the details of how this works at:
OAuth 2.0 for Mobile & Desktop Apps

The credentials.json file mentioned above is not an authorized set of user credentials. It consists of a client ID (public) identifier for your application and a client secret (private) known only to your application. Neither of these can be used to access your data, but they can be used to ask a user for permission to allow app access.

Your organization may have a policy disallowing data access from untrusted applications. In that case, you'll need your admin to trust your application (and your client ID). That's how the policy is intended to work.

A quick note on service accounts in Google Drive:
See the warning at Drive API - Authenticate your users. Generally speaking, service accounts should never act as themselves in Drive. They should only be used from an administrative capacity to impersonate users. They aren't, and shouldn't be relevant to your use case.

1
votes

problem

Your only option to access private user data is to be authorized as a user who can access the file. Either logging in using Oauth2 or using a service account

Downloading the credentials -- insecure and my organization prohibits it.

In order to use a google api you must first register your application on google developer console and download the client credentials then a user must authorize the application using Oauth2, which would mean both downloading the credentials.json file from google developer console and you getting user token credentials from the authorized user.

Sharing of google sheet with service account email. organization also prohibits sharing sheet with outside organization emails.

In order to use a service account you would again need to first register your application on google developer console and download the client credentials for the service account. Then you would need to share the sheet with the service account.

service account impersonation.

Service account impersonation is used by GSuite domain. You create a normal service account again downloading the credentials, and then the GSuite admin is able to delegate authority to the service account which will allow it to impersonate a user on the domain.

This would require you to have GSuite domain and the owner of the file being also on the GSuite domain, and you creating a project on google developer console and downloading the credentials.json for the service account, which you already stated you couldn't do.

conclusion

I guess what i am saying is there is no way with the limitations imposed by your organization for you to access a private google sheet or any private user data on googles system, via any api.