Google service account or OAuth for calendar access: which one, and why
Updated
TL;DR
Use a service account with domain-wide delegation only for your own Google Workspace domain: a super administrator grants it, and it can then act as any user in that domain without their consent. For a product whose users come from many companies or use personal Gmail, use OAuth: each user consents to your app, which needs Google's review for calendar scopes, and you keep a refresh token per user.
Two ways in
A service account is "an account that belongs to your application instead of to an individual end user". Your server signs in as it, "and user consent is not required." On its own, a service account has its own empty calendar and can only see calendars someone shares with it; service accounts "are not members of your Google Workspace account."
Domain-wide delegation lets the service account act as users in a Workspace domain. "A super administrator of the Google Workspace domain must complete the following steps": authorizing the service account's client ID for specific scopes in the Admin console, under Security, Access and data control, API controls. Your code then names the user to act as in the token's sub claim. Google's admin help is plain about the reach: "With domain-wide delegation, the app has access to the data belonging to all of your users." Changes "can take up to 24 hours."
OAuth asks each user. They see your app on Google's consent screen, approve the scopes, and you get a refresh token for that one person. (Google's OAuth overview)
When a service account fits
- Your own company's calendars. An internal tool that books rooms or reads every employee's schedule in your own Workspace.
- A single customer that will grant it. An integration built for one organization whose administrator is willing to give your service account domain-wide access.
What you avoid: the consent screen, refresh tokens per user, and their limits, since the cap of "100 refresh tokens per Google Account per OAuth 2.0 client ID" "does not apply to service accounts."
What you take on: a super administrator has to act in every domain, the access covers every user in it, and attendees need it. Without delegation, a service account creating events with attendees fails, because "Service accounts need to use domain-wide delegation of authority to populate the attendee list." More in why service accounts can't invite attendees.
When OAuth fits
- Users from many companies. Asking every customer's super administrator to delegate domain-wide access to you doesn't scale, and many won't.
- Personal Gmail accounts. Domain-wide delegation exists only for users in a Google Workspace domain. A Gmail user can't be impersonated.
- Consent per person. Each user decides, and can revoke, their own access.
What you take on: Google's review for calendar scopes before more than 100 users can sign in, refresh tokens to store and refresh, and tokens that stop working. See how long Google's OAuth review takes and storing calendar tokens safely.
A rule of thumb
If every calendar you need belongs to one Workspace domain whose administrator you can ask, a service account is simpler. If your users sign up on their own, from different companies or on Gmail, use OAuth.
How Pyas does it
Pyas connects each person's account with OAuth, so it works for Workspace and personal Gmail alike, with invitations sent from the person's own calendar:
- Pyas Auth is OAuth through an app Google has already verified, on every plan, so you skip the review.
- Native Auth uses your own OAuth client when you want your name on the consent screen.
- Already have users' refresh tokens?
POST /v2/accounts/importbrings existing accounts in, with your own OAuth client, without asking users to connect again.