1

I am trying to use the service account using Google Cloud Functions to access the Workspace Directory API. I am trying to use Application Default Credentials approach. Since the documentation doesn't mention any additional steps to be done in the Google Cloud Console side, I assume that Application Default Credentials (ADC) to the function is automatically passed to the cloud function from Google Cloud's Metadata server. The following code works perfectly in my local, emulated environment where I have set GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the JSON credential file. However when I deploy the function to Google Cloud, I am getting the error "Not Authorized to access this resource/api". I have been searching and trying for days without any success. As an aside, before I stumbled upon this thread, I was using getCredentials() method of GoogleAuth to get the private_key to create JWT auth (for the "subject" property) and passing that auth to admin API call. Which again worked perfectly in my local environment but fails in the cloud environment because getCredentials() private_key is null, which is probably expected behavior. Any help is deeply appreciated. I am inexperienced with posting in Stackoverflow, if I need to follow any other protocol, please advise.

export const listUsers = functions.https.onCall((data, context) => {
  return new Promise(async (resolve, reject) => {
    const envAuth = new GoogleAuth({
      scopes: ["https://www.googleapis.com/auth/admin.directory.user.readonly"],
      clientOptions: {
        subject: "admin@mydomain.com",
      },
    });

    const client = await envAuth.getClient();
    const service = google.admin({version: "directory_v1", auth: client});
    try {
      const response = await service.users.list({
        customer: "MYCUSTOMER_ID",
      });
      resolve(response);
    } catch (err) {
      reject(err);
    }
  });
});
Abdul Rauf
  • 5,798
  • 5
  • 50
  • 70
increos
  • 21
  • 3

1 Answers1

1

When you run a Cloud Function without authenticating via a key file (the json credential file that has the key to allow you to impersonate/authenticate as a different user), the function runs as the default application credentials for the project (<YOUR_CLOUD_PROJECT_ID>@appspot.gserviceaccount.com). You don't have to do anything special, no authentication calls -- it runs with the permissions of this service account by default.

When you run the code locally, it takes on the user authentication of whatever key file you have locally (and have referenced in the "GOOGLE_APPLICATION_CREDENTIALS" environment variable on your machine).

Without full security information on your environment, it's hard to know for sure... But, I'm guessing that you're trying to access resources that your personal Google Account has proper access; however, the default service account for you Cloud Functions Project does not.

So, couple of routes to troubleshoot and/or fix the issue:

  • Give the default service account access rights to Workspace resource(s) you're attempting to access.
  • Use the JSON key file you setup locally already, to have the Cloud Function run as the same user as is happening when you run locally.
  • Essentially do a hybrid where you create a new service account that ONLY has the permissions you want (instead of using the default service account or your personal user, both of which might have far more permissions then desired for safety/security), use a key file to run the Cloud Function under that identity, and only give the desired permissions to that service account.
Mike
  • 1,211
  • 1
  • 7
  • 6
  • Are you sure that you grant the service account email on your workspace resources? – guillaume blaquiere Dec 16 '21 at 19:56
  • 1
    Yes I have provided [domain wide delegation as described here](https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account) to Client ID associated with the service account with the correct scopes. And I believe that is how it is currently working locally. @Mike are you suggesting that I download the key file and store in storage etc and read from there ? But most documentation is advising against it. Thank you for your help. – increos Dec 16 '21 at 21:24
  • Suggest doing it to troubleshoot. Get it working with the fewest changes from your working, local setup. If using the key file works, then you know where to focus your attention (an issue on the service account permissions side). the best, final answer is likely option 3, so you can assign the least privileges required (it can have less privilege than the default project service account). But, I'd avoid doing that until after you've solved this blocking issue. – Mike Dec 18 '21 at 15:19