Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Google Drive API from a Google Cloud function

I've seen that there are different NodeJS modules that use Google APIs. What's the best practice to access files that are shared with the service account of a Google Cloud function?

like image 261
Ariel Avatar asked Apr 17 '17 17:04

Ariel


2 Answers

I develop mainly with Python, but it has a similar problem as Node that you mentioned: lots of libraries & too many differing code samples out there. Another issue is that accessing G Suite APIs (like Drive) is different than GCP APIs. (DISCLOSURE: I work at Google and am trying to improve this discrepancy.)

A service account identity is the best way to access the Drive API from GCF. However, you can choose either a Cloud Function's default service account identity (same for an App Engine app), or as another answer here suggested, a user-managed service account instead. The latter is a good idea if you're planning to have multiple identities that do different things, need differing types of access, etc., otherwise it's easier to use the default because you don't really have to do anything else other than create a private key-pair for that account.

Once you've decided on what type of service account, best to use the Google APIs Client Library for Node.js to talk to Drive, G Suite, and other non-GCP Google APIs. Follow the Drive API Node.js quickstart tutorial to learn how to "work it." Since Drive files typically belong to user accounts instead of service accounts, the auth example in the quickstart features OAuth client ID (user account) auth rather than service account auth to prompt the user (Drive owner) to give the app permission to access their data, so don't just cut-n-paste!

(If you're not using Cloud Functions, you're likely doing a web app or cmd-line tool. In that situation, if selecting user acct auth instead of service acct auth, end-users [Drive file owners] must explicitly grant permission via the familiar OAuth consent dialog for your code to access their files. As the developer, you'd need to setup that OAuth consent screen in the Cloud Console beforehand. NOTE: that screenshot was taken from my G Suite APIs intro tutorial [Python]).

Copy the necessary boilerplate from the sample and replace the user acct auth with service account auth. See the service account section of the Node.js client library docs on how to do it. Don't forget to create a private key-pair for whichever service account you decide to use from the Service accounts page and any roles/permissions it should have. It'll prompt you to download the key file once it's created, and then upload that w/your function (unless you use Secret Manager as suggested in another answer). By using client libraries, you avoid having to stick things in request headers (also as suggested in another answer). However, under no circumstances should you check that key file into Git if that's part of your CI/CD cycle; if your private key gets leaked/exposed publicly... DOOM shall befall you.

like image 59
wescpy Avatar answered Sep 30 '22 05:09

wescpy


The default behavior is as follows:

During function execution, Cloud Functions uses the service account [email protected] as its identity. For instance, when making requests to Google Cloud Platform services using the Google Cloud Client Libraries, Cloud Functions can automatically obtain and use tokens to authorize to the services this identity has permissions to use.

More information here.


Personal recommendation: it's good practice to use a purpose-specific service account which you'll need to securely store & not push into your version control -- meaning you can download and include it in your gcloud functions deploy scripts (so it'll be readable to the nodeJS runtime along with your package.json and actual function files) -- but always have it git-ignored.

If you want to be super secure, you can combine this approach with another google cloud product called Secret Manager. The nodeJS implementation of which is here. The disadvantage of this, though, is the amount of time between the function start-up and the deciphering of the encrypted JSON (since it's a network operation itself.)


There is one more important thing to know -- the drive API token -- already answered here: https://stackoverflow.com/a/58842310/8160318.

like image 38
Joe - Elasticsearch Handbook Avatar answered Sep 30 '22 05:09

Joe - Elasticsearch Handbook