0
votes

I am still struggling with Google's terminology of apis and services but my goal is to have automated functions via aws lambda which act on a G Suite Account (domain?) or more specific on users of this domain.

For now I just want to list all users of that domain. I run this code locally for testing.

What I have done:

This is the implementation:

const { google } = require("googleapis");

const auth = new google.auth.GoogleAuth({
keyFile: "credentials.json",
scopes:
  "https://www.googleapis.com/auth/drive.readonly,https://www.googleapis.com/admin/directory/v1, https://www.googleapis.com/auth/admin.directory.group, https://www.googleapis.com/auth/admin.directory.user",
 });

const service = google.admin({ version: "directory_v1", auth });
service.users.list(
{
  domain: "my.domain.com",
  maxResults: 10,
  orderBy: "email",
},
(err, res) => {
  if (err) return console.error("The API returned an error:", err.message);

  const users = res.data.users;
  if (users.length) {
    console.log("Users:");
    users.forEach((user) => {
      console.log(`${user.primaryEmail} (${user.name.fullName})`);
    });
  } else {
    console.log("No users found.");
  }
}
);

I am not sure why I have to add the scopes in the GoogleAuth object but I took this from the google documentation.

When I run this I get the following error:

The API returned an error: invalid_scope: Invalid OAuth scope or ID token audience provided.

1
So right now you are running your code locally for testing, for your domain and you are the admin of this domain?ziganotschka
yes, that is correct. but the credentials are the one from the service account. And it definitely has all the scopeszlZimon

1 Answers

1
votes
  • The Directory API can only be used by admins
  • A Service account is not an admin
  • If the service account shall act on behalf on the admin, you need to
    • enable G Suite Domain-wide Delegation (as you already did)
    • impersonate the service account as the admin by setting the user to be impersonated

In general, when you are using a service account you need to build the authentication flow, as explained in the documentation, that is you need to create JSON Web Token (JWT) specifying the user to impersonate.

A sample code snippet for Javascript:

        const jwtClient = new google.auth.JWT(
            privatekey.client_email,
            null,
            privatekey.private_key,
            scopes,
            user // User who will be impersonated (needs to be an admin)
        );

        await jwtClient.authorize();

        return jwtClient;