3

I would like to rig things so that my GCP service account can invite users to calendar events. So for example my-service-account@myproject.iam.gserviceaccount.com would invite user@myCorporation.com to an event. It seems to me that this should be possible simply by giving my-service-account@myproject.iam.gserviceaccount.com permission to use the Calendar API, without having user@myCorporation.com grant any additional permissions.

I tried to implement this example, but replaced the compute scope and the compute API calls with the calendar scope and calendar API calls. My code is returning the error

Insufficient Permission: Request had insufficient authentication scopes.

I've poked around on the internet a bunch, and I cannot tell if the problem is that I did something wrong or if the problem is that Google does not support what I'm trying to do.

Here is my code:

const {google} = require('googleapis');
const compute = google.compute('v1');

const {GoogleAuth} = require('google-auth-library');

async function main() {
  const auth = new GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/calendar',
      'https://www.googleapis.com/auth/compute']
  });

  //keeping the compute stuff in as a sanity check
  //to ensure that the problem is with calendar, not something more general
  const authClient = await auth.getClient();
  const project = await auth.getProjectId();
  const res = await compute.zones.list({project, auth: authClient});
  console.log(res.data);

  createEvent(auth);
}

/**
 * Lists the next 10 events on the user's primary calendar.
 * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
 */
function createEvent(auth) {
  const calendar = google.calendar({version: 'v3', auth});
  calendar.events.insert({
        calendarId: 'primary',
        event: {
          "description": "my test event",
          "start": {
            "date": "2020-05-20",
          },
          attendees: [{email: "myGuest@mailinator.com"}]
        }
      }
  );
}

main().catch(console.error);
Nimantha
  • 6,405
  • 6
  • 28
  • 69
bashkirin
  • 75
  • 2
  • 10
  • Can you please provide your sanitised code? In order to create a calendar event you need the `https://www.googleapis.com/auth/calendar` scope. Service accounts can be tricky so it's nigh-on impossible to get t othe root cause without as much information as possible – Rafa Guillermo May 12 '20 at 12:18
  • @RafaGuillermo thank you for responding! I updated the question with my code. – bashkirin May 12 '20 at 16:24
  • 1
    This seems okay. Have you enabled the Calendar API for the GCP project to which your service account is tied? Also, in the [admin console](https://admin.google.com) under `Security > Advanced Settings > Manage API client access`, make sure that you have provided the project with the calendar scopes. If you're not doing delegation, double check that you have invited the service account email to the calendar too, (though this shouldn't flag this error it's worth a sanity check) – Rafa Guillermo May 13 '20 at 07:04
  • That might be the problem! I am an admin of the GCP project, and I just double checked that the calendar api is enabled. But I have no G Suite admin permissions. I cannot even access the admin console. Do I need to get a G Suite admin grant my project permissions? – bashkirin May 13 '20 at 14:26
  • You will do, yes. The Service account will need the scopes set in the admin console and only a domain admin can do this. I've added this as an answer below – Rafa Guillermo May 13 '20 at 15:03

1 Answers1

3

Answer:

You need to enable the APIs and provide scopes in three places: in your auth code, in the GCP console, and the Google Admin console.

More Information:

As I explained in the comments, the code you have provided should run without issue. The Insufficient Permission: Request had insufficient authentication scopes. error is a result of the service account not being given access to the required scopes somewhere on Google's side.

Make sure you have completed the following steps:

  1. Provided the scopes in the application as an auth object (which you have already done):
const auth = new GoogleAuth({
    scopes: ['https://www.googleapis.com/auth/calendar',
      'https://www.googleapis.com/auth/compute']
  });
  1. Enabled the Calendar API in the GCP console for your Service Account GCP Project.
  2. Provided the required scopes for your service account in the OAuth consent screen settings in GCP.
  3. Added the required scopes to the service account in the Google Admin console. This is done by following the Security > Advanced Settings > Manage API client access UI elements, and assigning all scopes the service account needs to the service account client ID.

Note: This final step must be done by a domain admin and can not be done by anyone who is not.

In this case, you will need to contact your domain admin to give your project API access.

References:


Related Answers:

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Rafa Guillermo
  • 14,474
  • 3
  • 18
  • 54
  • Are you sure this is accurate? My internal G Suite team says that what I'm trying to do is impossible, as service accounts do not have calendars. – bashkirin Jun 12 '20 at 14:27
  • @bashkirin Completely. Service accounts *do* have calendars, but as they are not part of your domain (they belong to `service-acc-project.iam.gserviceaccount.com`) you do not have access to view them without using the service account itself. – Rafa Guillermo Jun 12 '20 at 14:46