Skip to content

Basics

Apps Script permissions and authorization

Before a script can read your sheet or send your mail, you give it permission to access a list of OAuth scopes. This page walks through each authorization screen, explains @OnlyCurrentDoc, and shows how to revoke access.

1 of 8

A scope is one kind of access

A scope is one kind of access to your Google account, written down as a short label. "See, edit, create, and delete all your Google Sheets spreadsheets" is one scope. "Send email as you" is another. Approving a scope means the script may do that kind of thing whenever it runs.

Apps Script normally detects scopes from the services your code calls before authorization. Call SpreadsheetApp and it detects a spreadsheet scope. Call GmailApp as well and a mail scope is added. Automatic detection can be broader than the access your code needs.

You can inspect the detected list under Overview, in Project OAuth Scopes. You can also set the oauthScopes field explicitly in appsscript.json when you need to control the list; that field is optional and is not added automatically after a run.

  • Scopes cover a kind of access, not one file. A spreadsheet scope is usually about all of your spreadsheets, not the one you opened.
  • The list is per project. Two Apps Script projects each ask for their own approval.
  • Use Overview > Project OAuth Scopes to inspect the automatically detected list. Project Settings has a checkbox to show the appsscript.json manifest, where you may set oauthScopes explicitly.

2 of 8

How to grant permission, screen by screen

The first run of a project that touches your data opens a window titled "Authorization required". It says the project needs your permission to access your data. There is one button: Review permissions.

Next you choose the Google account you want the script to act as. If you are signed in to several accounts, check which one you pick. The account you pick here is the account whose files and mail the script will use.

Then Google may show a screen headed "Google hasn't verified this app". Click Advanced at the bottom left, then the link that reads "Go to <project name> (unsafe)". The last screen lists the access being requested and ends with Cancel and Allow.

  • Authorization required, then Review permissions.
  • Choose an account.
  • Google hasn't verified this app, then Advanced, then Go to <project name> (unsafe).
  • Read the list, then Allow.

3 of 8

Why your own script is "unverified"

Google reviews apps that ask the public for access, and gives them a verified badge. Your project is a few lines you wrote this morning, so it has never been through that review. The warning appears for every new personal project, and it is not a sign that anything is wrong.

The warning is doing real work, though. It looks the same when the script was written by somebody else and sent to you. The question to ask is not "is it verified" but "do I know who wrote this code, and can I read it".

If a stranger sent you a link to a script, open the code and read it before you approve anything. If you cannot read it, do not approve it.

4 of 8

Match the list to what the code does

The last screen is a list of sentences, each one a scope in plain words. Read it against the code you are about to run. A script that copies rows between tabs should ask about spreadsheets. If it also asks to send mail as you, and you cannot find a line that sends mail, stop and reread the code.

In a project that leaves automatic scope detection on, the function below reads one thing: the name of the sheet tab you are looking at. Because SpreadsheetApp is the only service it calls, the dialog asks only for spreadsheet access. Nothing about mail, Drive, or your calendar appears.

Automatic detection for a function that only touches spreadsheets
function logActiveSheetName() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  Logger.log('The active sheet is called ' + sheet.getName() + '.');
}

5 of 8

How to take the access back

Go to https://myaccount.google.com/permissions. That page lists everything you have approved, including your own Apps Script projects, which appear under their project names.

Click the project, then Remove access. The approval is gone. The code is untouched, so the next time you run it the authorization dialog appears again and you can approve a fresh list.

Revoking deletes nothing in your sheets, mail, or Drive. Installed triggers for that project stop working until you approve again.

6 of 8

Deleting code does not remove access

When you let Apps Script detect scopes, adding a GmailApp line makes the next run ask for mail access. Deleting that line later does not hand the access back. The approval you already gave stays on your account until you revoke it.

So a project that once sent a test email keeps its mail approval even after the mail code is gone. With automatic detection, remove the code, then revoke the project at the permissions page, then run again and approve the smaller list. If you set oauthScopes explicitly, update that list too.

Do this after you experiment. A project that only needs to read a sheet should not be sitting on approval to send mail as you.

7 of 8

Limit supported editor services to the current file

A bound Sheets, Docs, Slides, or Forms project that only works with the open file can add the @OnlyCurrentDoc annotation. Apps Script then requests the matching currentonly scope instead of access to every file of that editor type. This is a useful least-privilege boundary and usually produces a clearer consent screen.

Current-only access applies to supported built-in Apps Script services. It does not cover advanced services or direct calls to Google Workspace REST APIs. Those paths need their normal API scopes. DriveApp, GmailApp, CalendarApp, and other unrelated services are not narrowed by this annotation.

Code with @OnlyCurrentDoc must stay inside the current container. Methods such as SpreadsheetApp.openById or openByUrl need broader spreadsheet access because they can select another file. If a library declares @OnlyCurrentDoc but the main project truly needs broader access, @NotOnlyCurrentDoc opts the main project back out.

After adding or removing either annotation, inspect Overview > Project OAuth Scopes. If the project was already authorized, revoke and authorize it again to see the new consent boundary.

Request access only to the open spreadsheet
/**
 * @OnlyCurrentDoc
 */
function logCurrentSheetName() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  Logger.log(sheet.getName());
}

8 of 8

Your account and the account behind a trigger

When you press Run, the code acts as you. Session.getEffectiveUser() is your address, GmailApp sends from your mailbox, and DriveApp writes into your Drive.

A trigger is different. A trigger is a rule that runs a function without you, for example every day at seven, or whenever a form is submitted. It runs as the account that created it, using that account's approvals, even when somebody else caused it to fire.

If a colleague edits the spreadsheet and your installable trigger sends an email, the email comes from you and counts against your daily limit. If they install their own copy of the trigger, they approve their own access and it runs as them.

  • Whoever clicks the button in the Triggers panel is the owner of that trigger.
  • The owner gets the failure notification emails when the trigger errors.
  • If the owner revokes access at the permissions page, their triggers stop running.

Remember

The short version

  • Apps Script normally detects scopes from the services your code calls; inspect them under Overview > Project OAuth Scopes or set oauthScopes explicitly in appsscript.json.
  • The unverified warning is normal for your own project, so the real question is whether you trust the code.
  • Read the list on the last screen and match every line to something the code actually does.
  • @OnlyCurrentDoc narrows supported built-in editor services to the open file, but it does not narrow advanced services, direct REST calls, or unrelated Google services.
  • Revoke at https://myaccount.google.com/permissions, because deleting the code does not take the access back.
  • A trigger runs as the account that created it, with that account's approvals and mail.

Keep going

Put it to work

All basics