When you turn a Google Apps Script into a web app, the most common stumbling block is the permission set‑up. The short answer is: define only the OAuth scopes your script really needs, set the correct Execute as and Who has access options when you deploy, and then re‑deploy any time the scope list changes.
Understanding Apps Script Permissions (OAuth Scopes)
Every Apps Script runs under a set of OAuth scopes – essentially a list of Google services the script is allowed to touch. Scopes are declared in the appsscript.json manifest file. If you never add a scope manually, Apps Script adds a default set based on the services you call, but it may grant more access than you intend.
- Read‑only scopes (e.g., https://www.googleapis.com/auth/spreadsheets.readonly) let the script view data but not change it.
- Read‑write scopes (e.g., https://www.googleapis.com/auth/spreadsheets) let the script edit data.
- Broad scopes such as https://www.googleapis.com/auth/drive give full Drive access and should be used sparingly.
To see which scopes your project currently requests, open the script editor, click the gear icon → Project settings**, and scroll to **Scopes**. You can also view the generated appsscript.json file by selecting View → Show manifest file.
Configuring Permissions for a Web App
Deploying a script as a web app adds two more decisions: who the script runs as, and who can access it.
- Open the script project in the Apps Script editor.
- Set explicit scopes in the manifest. Add a oauthScopes array with only the needed entries, for example: { "timeZone": "Asia/Karachi", "oauthScopes": [ "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/script.external_request" ] }
- Deploy as a web app (Deploy → New deployment → Select type > Web app).
- Choose Execute the app as:
- Me (owner) – the script runs with your account’s permissions. Use this when the app needs to read/write your private Sheets.
- User accessing the web app – each visitor must grant consent, and the script can only act on data they own.
- Choose Who has access:
- Anyone – open to the public (good for a public form).
- Anyone with the link – slightly more controlled.
- Only myself – for internal tools.
- Click **Deploy** and copy the generated URL.
Remember: after any change to oauthScopes, you must re‑deploy the web app; otherwise the old scope set remains active.
Example: Simple Order Tracker Using Google Sheets
Suppose you need a tiny web form that records a new order line in a shared Google Sheet. The script only reads the sheet to append a row, and it sends a confirmation email. The required scopes are:
- https://www.googleapis.com/auth/spreadsheets – to write rows.
- https://www.googleapis.com/auth/mail.send – to send the email.
Manifest snippet:
{ "timeZone": "Asia/Riyadh", "oauthScopes": [ "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/mail.send" ] }Minimal server‑side code (do not copy‑paste without testing):
function doPost(e) { var ss = SpreadsheetApp.openById('YOUR_SHEET_ID'); var sheet = ss.getSheetByName('Orders'); var data = JSON.parse(e.postData.contents); sheet.appendRow([new Date(), data.customer, data.product, data.quantity]); MailApp.sendEmail(data.email, 'Order Received', 'Thanks for your order!'); return ContentService.createTextOutput('OK').setMimeType(ContentService.MimeType.TEXT); }Deploy as a web app, choose **Execute the app as: Me**, and set **Who has access: Anyone with the link**. The form on your site can now POST JSON to the URL without exposing your credentials.
Testing, Logs, and Recovering from Permission Errors
After deployment, test the endpoint with a tool like Postman or a simple curl command. If the script lacks a required scope, the execution will fail with an error such as:
Exception: You do not have permission to call SpreadsheetApp.openById (line 2).To diagnose:
- Open **View → Logs** in the script editor to see the full stack trace.
- Check the **Execution transcript** under My executions** in the Apps Script dashboard for the specific user that triggered the error.
- If the error mentions a missing scope, add it to oauthScopes, save the manifest, and re‑deploy.
When you change scopes, each existing user may be prompted to re‑authorize the app the next time they interact with it. That is normal and ensures the new permissions are granted.
Common Mistakes and How to Fix Them
- Over‑granting scopes – Using a broad Drive scope when only Sheets access is needed. Fix: replace https://www.googleapis.com/auth/drive with the specific Sheets scope.
- Forgetting to re‑deploy after manifest edits – The old deployment continues to run with the previous scope set. Fix: always click **Deploy → Manage deployments**, select the version, and click **Update**.
- Choosing the wrong "Execute as" option – Selecting “User accessing the web app” when the script needs to write to a private sheet you own. Fix: switch to “Me (owner)”.
- Leaving the web app open to the public unintentionally – Setting “Anyone” for a tool that handles sensitive data. Fix: restrict access to “Only myself” or “Anyone with the link” and share the link securely.
- Missing trigger permissions – If you add an installable trigger (e.g., time‑driven) but forget the script.external_request scope, the trigger will fail. Fix: add the required scope and redeploy.
Checklist Before Publishing Your Apps Script Web App
- Identify every Google service the script touches (Sheets, Gmail, Drive, etc.).
- List the minimal OAuth scopes needed for those services.
- Update appsscript.json with the exact oauthScopes array.
- Save the manifest and run a test function in the editor to confirm no “missing scope” errors.
- Deploy as a new version of the web app.
- Select **Execute the app as** (owner vs. user) based on data ownership.
- Choose the appropriate **Who has access** setting.
- Test the live URL with real data (use a staging sheet if possible).
- Check logs for any unexpected permission prompts.
- Document the required scopes for future team members.
Conclusion
Setting the right permissions for a Google Apps Script web app is a matter of clarity: know exactly which Google services you need, declare only those scopes, and align the deployment options with who should run the code. By following the steps and checklist above, you can avoid the dreaded “You do not have permission” errors, keep your data secure, and launch a reliable automation tool.
If you need a ready‑made solution for an ecommerce order form backed by Google Sheets, check out the Apps Script ecommerce source‑code package. For help with deployment, custom workflows, or troubleshooting permissions, feel free to contact us.