Authorization Scopes

Users must authorize script projects that access their data or act on their behalf. When a user runs a script that requires authorization for the first time, the UI presents a prompt to start the authorization flow.

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

For most scripts, Apps Script automatically detects what scopes are needed for you; you can view the scopes a script uses at any time. You can also set scopes explicitly in your manifest using URL strings. Setting scopes explicitly is sometimes required for certain applications like add-ons, since published applications should always use the narrowest scopes possible.

During the authorization flow, Apps Script presents human-readable descriptions of the required scopes to the user. For example, if your script needs read-only access to your spreadsheets, the manifest may have the scope https://www.googleapis.com/auth/spreadsheets.readonly. During the authorization flow, a script with this scope asks the user to allow this application to "View your Google Spreadsheets".

Some scopes are inclusive of others. For example, when authorized the scope https://www.googleapis.com/auth/spreadsheets allows read and write access to spreadsheets.

For some surfaces where scripts run, such as running a script directly from the Apps Script IDE, users are presented with the granular OAuth consent screen. This lets users select specific permissions to grant rather than granting all permissions at once. It's important to design your script to handle granular OAuth permissions.

View scopes

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

  1. Open the script project.
  2. At the left, click Overview .
  3. View the scopes under Project OAuth Scopes.

Set 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, web apps, Google Chat apps, and calls to Google Chat API you must exercise more direct control of the scopes.

Apps Script sometimes automatically assigns projects very permissive scopes. This can mean your script asks the user for more than it needs, which is bad practice. For published scripts, you must replace broad scopes with a more limited set that cover the script'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 project. To set your project's scopes, do the following:

  1. Open the script project.
  2. At the left, click Project Settings .
  3. Select the Show "appsscript.json" manifest file in editor checkbox.
  4. At the left, click Editor .
  5. At the left, click the appsscript.json file.
  6. Locate the top-level field labeled oauthScopes. If it's not present, you can add it.
  7. 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/spreadsheets.readonly",
              "https://www.googleapis.com/auth/userinfo.email"
            ],
           ...
          }
  8. At the top, click Save .

Handle granular OAuth permissions

The granular OAuth consent screen lets users specify which individual OAuth scopes they want to authorize. Granular OAuth permissions give users more fine-grained control over what account data they choose to share with each script. For example, imagine you develop a script that requests permission for both email and calendar scopes. Your users might want to use your script only for its capabilities with Google Calendar, but not Gmail. With granular OAuth permissions, users can choose to only grant Calendar permission, but not Gmail.

The following sections describe the main ways to handle granular OAuth permissions.

Automatically require permission for necessary scopes

If an execution flow needs permission for scopes in order to work, you can require users to grant those permissions before they can use it. Your script can check if the user has already given permission and, if not, automatically ask them for it.

The following methods from the ScriptApp class let you validate permission for required scopes and automatically render the authorization prompt to request any missing permissions:

Example

The following example shows how to call the requireScopes(authMode, oAuthScopes) and requireAllScopes(authMode) methods. The script uses scopes for Gmail, Sheets, and Calendar. The sendEmail() function requires only the scopes for Gmail and Sheets while the createEventSendEmail() function requires all scopes used by the script.

// This function requires the Gmail and Sheets scopes.
function sendEmail() {
  // Validates that the user has granted permission for the Gmail and Sheets scopes.
  // If not, the execution ends and prompts the user for authorization.
  ScriptApp.requireScopes(ScriptApp.AuthMode.FULL, [
    'https://mail.google.com/',
    'https://www.googleapis.com/auth/spreadsheets'
  ]);

  // Sends an email.
  GmailApp.sendEmail("dana@example.com", "Subject", "Body");
  Logger.log("Email sent successfully!");

  // Opens a spreadsheet and sheet to track the sent email.
  const ss = SpreadsheetApp.openById("abc1234567");
  const sheet = ss.getSheetByName("Email Tracker")

  // Gets the last row of the sheet.
  const lastRow = sheet.getLastRow();

  // Adds "Sent" to column E of the last row of the spreadsheet.
  sheet.getRange(lastRow, 5).setValue("Sent");
  Logger.log("Sheet updated successfully!");
}

// This function requires all scopes used by the script (Gmail,
// Calendar, and Sheets).
function createEventSendEmail() {
  // Validates that the user has granted permission for all scopes used by the
  // script. If not, the execution ends and prompts the user for authorization.
  ScriptApp.requireAllScopes(ScriptApp.AuthMode.FULL);

  // Creates an event.
  CalendarApp.getDefaultCalendar().createEvent(
    "Meeting",
    new Date("November 28, 2024 10:00:00"),
    new Date("November 28, 2024 11:00:00")
  );
  Logger.log("Calendar event created successfully!");

  // Sends an email.
  GmailApp.sendEmail("dana@example.com", "Subject 2", "Body 2");
  Logger.log("Email sent successfully!");

  // Opens a spreadsheet and sheet to track the created meeting and sent email.
  const ss = SpreadsheetApp.openById("abc1234567");
  const sheet = ss.getSheetByName("Email and Meeting Tracker")
  // Gets the last row
  const lastRow = sheet.getLastRow();

  // Adds "Sent" to column E of the last row
  sheet.getRange(lastRow, 5).setValue("Sent");
  // Adds "Meeting created" to column F of the last row
  sheet.getRange(lastRow, 6).setValue("Meeting created");
  Logger.log("Sheet updated successfully!");
}

Create a custom experience for missing scopes

You can get the permission details of the user running your script and design a custom experience based on their permission status. For example, you might decide to turn off specific features of your script that require permissions that the user hasn't granted, or present a custom dialog explaining the missing permissions. The following methods get an object with the user's permission information that includes which scopes the user has authorized and a URL to let you request any missing scopes:

To get the permission details from the authorization info object, such as a list of which scopes have been authorized and a URL to request missing permissions, use the methods from the AuthorizationInfo class.

Example

The following example shows how to call the getAuthorizationInfo(authMode, oAuthScopes) method to skip specific features within an execution flow where the required scopes haven't been granted. This lets the rest of the execution flow continue without having to prompt for authorization of the missing scopes.

// This function uses the Gmail scope and skips the email
// capabilities if the scope for Gmail hasn't been granted.
function myFunction() {
  const authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL, ['https://mail.google.com/']);
  if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.NOT_REQUIRED) {
    GmailApp.sendEmail("dana@example.com", "Subject", "Body");
    Logger.log("Email sent successfully!");
  } else {
    const scopesGranted = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL).getAuthorizedScopes();
    console.warn(`Authorized scopes: ${scopesGranted} not enough to send mail, skipping.`);
  }
  // Continue the rest of the execution flow...
}

OAuth verification

Certain OAuth scopes are sensitive because they allow access to Google User Data. If your script project uses scopes that allow access to user data, the project must go through OAuth client verification before you can publish it publicly as a web app or add-on. For more information, see the following guides:

Restricted scopes

In addition to sensitive scopes, certain scopes are classified as restricted and subject to additional rules that help protect user data. If you intend to publish a web app or add-on that uses one or more restricted scopes, the app must comply with all the specified restrictions before it can be published.

Review the full list of restricted scopes before you attempt to publish. If your app uses any of them, you must comply with the Additional Requirements for Specific API scopes prior to publishing.