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, then 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 own new project has not been through that review. The warning appears for every new personal project, and it is not a sign that anything is wrong.
The same warning appears for a script that somebody else wrote and sent to you. Before you approve, check who wrote the code and whether you can 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.
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 remove the project's access 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 keep permission 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 limits the script to the open file 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 needs broader access, @NotOnlyCurrentDoc opts the main project back out.
After adding or removing either annotation, inspect Overview, then Project OAuth Scopes. If the project was already authorized, revoke and authorize it again to see the new list of scopes.
/**
* @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 click 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, then Project OAuth Scopes, or set oauthScopes explicitly in appsscript.json.
- The unverified warning is normal for your own project, so decide based on 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
- Task guide Send an email for each row in a Google Sheet
Send one email to each person listed on a Customers tab. The script marks each row Sent as it goes, so a later run sends only to rows that are not marked yet.
- Task guide Run an Apps Script function every day
Make a function run on its own once a day. Run the setup function once, and from then on Apps Script calls the reminder function each day around the hour you chose.
- Task guide Save labeled Gmail attachments to Drive
Copy the attachments from chosen Gmail conversations into one Drive folder. You pick the conversations by adding a label to them, and the script saves every attachment it finds there.
- Basics Run your first Apps Script function
Your first script, from opening the editor to reading its output. You replace the starter function, save, click Run, and read what Logger.log printed in the Execution log.
- Basics Google Apps Script triggers explained
Google Apps Script triggers run functions automatically when a file opens, a cell changes, a form is submitted, or a scheduled time arrives. Use a simple onEdit or onOpen for work in the bound file. Choose an installable trigger for a schedule, form submission, or work that needs authorization.
- Basics Common Apps Script errors and what they mean
Apps Script error messages say what failed, for example TypeError: Cannot read properties of null (reading 'getRange') or ReferenceError. Find the exact message below for its cause and fix.