Authorization Scopes

Users must authorize add-ons and other applications that access their data or act on their behalf. When a user runs an add-on for the first time, the UI presents an authorization prompt to start the authorization flow.

During this flow, the UI tells the user what the application wants permission to do. For example, an add-on might want permission to read the user's email messages or create events in their calendar. The add-on's script project defines these individual permissions as OAuth scopes.

You declare scopes in your manifest using URL strings. During the authorization flow, Apps Script presents a human-readable description of the scope to the user. For example, all Gmail add-ons require the "Add-on Execution" scope, which in your manifest is written as https://www.googleapis.com/auth/gmail.addons.execute. During the authorization flow, a script with this scope asks the user to allow this application to "Run as a Gmail add-on".

Viewing scopes

You can see the scopes your script project currently requires by doing the following:

  1. Open the script project in the Apps Script editor.
  2. In the menu, select File > Project properties.
  3. Select the Scopes tab.

Setting explicit scopes

Apps Script automatically determines what scopes a script needs by scanning its code for function calls that require them. For most scripts this is sufficient and saves you time, but for published add-ons you should exercise more direct control of the scopes.

By default, Apps Script typically gives projects such as Gmail add-ons a very permissive scope https://mail.google.com. When a user authorizes a script project with this scope, the project is granted full access to the user's Gmail account. For published add-ons, you must replace this scope with a more limited set that cover the add-on's needs and no more.

You can explicitly set the scopes your script project uses by editing its manifest file. The manifest field oauthScopes is an array of all scopes used by the add-on. To set your project's scopes, do the following:

  1. Open the script project in the Apps Script editor.
  2. In the menu, select File > Project properties.
  3. Select the Scopes tab.
  4. Review the scopes your add-on currently requires and determine what changes need to be made. Click Cancel when finished.
  5. If the manifest file appsscript.json isn't visible in the left nav bar, select the View > Show manifest file menu item.
  6. Select the appsscript.json file in the left nav to open it.
  7. Locate the top-level field labeled oauthScopes. If it is not present, you can add it.
  8. The oauthScopes field specifies an array of strings. To set the scopes your project uses, replace the contents of this array with the scopes you want it to use. For example:

    {
      ...
      "oauthScopes": [
        "https://www.googleapis.com/auth/gmail.addons.execute",
        "https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
        "https://www.googleapis.com/auth/userinfo.email"
      ],
      "gmail": {
        ...
      }
    }
    
  9. Save the manifest file using Ctrl+S or the Save file icon in the menu bar.

Gmail add-on scopes

The following are scopes frequently used in conjunction with Gmail add-ons. Be sure to replace the very broad https://mail.google.com scope in your add-on with the set of scopes that allow the interactions your add-on needs and no more.

Scope Description
https://www.googleapis.com/auth/gmail.addons.execute Required. Runs as a Gmail add-on.
https://www.googleapis.com/auth/gmail.addons.current.message.metadata Grants temporary access to the open message's metadata (such as the subject, recipients, etc.). Does not allow reading of message content and requires an access token.
https://www.googleapis.com/auth/gmail.addons.current.message.action Grants access to the open message's content upon a user interaction, such as when a add-on menu item is selected. Requires an access token.
https://www.googleapis.com/auth/gmail.addons.current.message.readonly Grants temporary access to the open message's metadata and content. Requires an access token.
https://www.googleapis.com/auth/gmail.addons.current.action.compose Allows the add-on to temporarily create new drafts via Compose actions. Requires an access token.
https://www.googleapis.com/auth/gmail.readonly Read any email metadata and content, including the open message. Required if you need to read information about other messages, such as when conducting a search query or reading an entire mail thread. This is a very broad Gmail scope and should only be used if absolutely necessary.

In addition, if your add-on uses other Apps Script services you may need to include additional scopes. In most cases you can let Apps Script detect these scopes and update the manifest automatically. When editing your manifest's scope list, do not remove any scopes unless you are replacing them with a more appropriate alternative, such as a narrower scope.

For reference, here is a list of Apps Script scopes that often are used in conjunction with Gmail add-ons:

Scope Description
https://www.googleapis.com/auth/userinfo.email Allows the project to learn the current user's email address.
https://www.googleapis.com/auth/script.storage Allows the project to read and write Properties.
https://www.googleapis.com/auth/script.external_request Allows the to make UrlFetch requests. This is also required if the project makes use of the OAuth2 for Apps Script library.

Access tokens

To protect user data, the Gmail add-on scopes only grant temporary access to user data. To enable this access, you must call the function GmailApp.setCurrentMessageAccessToken(accessToken) using an access token as an argument. You must obtain an access token from an action event object.

The following shows an example of setting an access token to allow access to a message's metadata. The only scope necessary for this example is https://www.googleapis.com/auth/gmail.addons.current.message.metadata.

function readSender(e) {
  var accessToken = e.messageMetadata.accessToken;
  var messageId = e.messageMetadata.messageId;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  var mailMessage = GmailApp.getMessageById(messageId);
  return mailMessage.getFrom();
}