Author: By Raj

Part of our Google Apps Script Consulting guides. Need this built for your team? Hire a Google Apps Script developer.

Estimated reading time: 10 minutes

Using Service Accounts in Google Apps Script for Server-to-Server Auth

Service accounts let server-style code act without a human clicking authorize, critical for nightly ETL and signing JWTs to Google APIs or third parties. In Apps Script, patterns differ from Cloud Run but the crypto is the same.

Domain-wide delegation allows a service account to impersonate Workspace users for Gmail or Drive access, powerful and sensitive. Store private keys in Script Properties or, preferably, pass short-lived tokens from a secure vault.

This article explains when Apps Script alone suffices versus when to keep keys only on Cloud Run. Cross-read /blog/apps-script-oauth2-guide for user-delegated OAuth flows.

Service account fundamentals

Create the account in Google Cloud Console, download JSON keys once, and restrict IAM roles to the minimum API scopes. Rotate keys on a calendar schedule.

Apps Script can sign JWTs with Utilities.computeRsaSha256Signature when you paste the key material into Script Properties, acceptable only for low-risk internal tools.

Domain-wide delegation

Workspace super admins authorize the client ID with explicit OAuth scopes in Admin Console. Without delegation, service accounts cannot read user mailboxes.

Audit which scripts impersonate whom. Prefer group aliases and shared drives when possible to reduce personal mailbox access.

JWT bearer token exchange

Build a JWT with iss (client email), scope, aud (token endpoint), and exp (~1 hour). Exchange it for an access_token via UrlFetchApp.post to oauth2.googleapis.com/token.

Cache access tokens in CacheService or Script Properties with expiry timestamps to avoid signing every fetch.

When not to put keys in Script

Regulated environments should keep private keys on Cloud Run with Secret Manager; Apps Script calls HTTPS endpoints you control.

User OAuth via the OAuth2 library is simpler for SaaS APIs like HubSpot when a human can authorize once, see /blog/apps-script-hubspot-integration.

Example code

function getServiceAccountToken() {
  const props = PropertiesService.getScriptProperties();
  const clientEmail = props.getProperty('SA_EMAIL');
  const privateKey = props.getProperty('SA_PRIVATE_KEY').replace(/\\n/g, '\n');
  const now = Math.floor(Date.now() / 1000);
  const header = Utilities.base64EncodeWebSafe(JSON.stringify({ alg: 'RS256', typ: 'JWT' }));
  const claim = Utilities.base64EncodeWebSafe(JSON.stringify({
    iss: clientEmail,
    scope: 'https://www.googleapis.com/auth/spreadsheets',
    aud: 'https://oauth2.googleapis.com/token',
    exp: now + 3600,
    iat: now,
  }));
  const sig = Utilities.computeRsaSha256Signature(header + '.' + claim, privateKey);
  const jwt = header + '.' + claim + '.' + Utilities.base64EncodeWebSafe(sig);
  const res = UrlFetchApp.fetch('https://oauth2.googleapis.com/token', {
    method: 'post',
    payload: { grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: jwt },
  });
  return JSON.parse(res.getContentText()).access_token;
}
ApproachBest forTradeoff
Apps Script nativeGoogle Workspace-centric workflows6-min limit, quotas
Zapier / MakeNo-code, many connectorsPer-task cost, vendor lock-in
Python + CloudHeavy data / MLHosting cost, separate auth
Google Apps Script consultingProduction custom logicBuild cost, you own code

FAQ

Can Apps Script use default compute credentials?

No. Apps Script projects are not GCP VMs. You must supply explicit credentials via JWT, OAuth user flow, or call a middle-tier you host.

Is storing a private key in Script Properties safe?

Only editors of the script project can read properties, but anyone with edit access is trusted. For stricter controls, keep keys off-Workspace in Secret Manager.

What scopes are needed for Sheets-only ETL?

Often https://www.googleapis.com/auth/spreadsheets or drive.file if using picker-based access. Avoid https://mail.google.com/ unless mail access is essential.

How does delegation differ from shared drives?

Shared drives grant group access without impersonation. Delegation lets code act as user@company.com, use only when business logic requires personal Drive paths.

Can service accounts send Gmail?

With domain-wide delegation and Gmail API scopes, yes, but many teams instead use MailApp as the installing user for simpler audit trails.

Need this done for you? I handle this as part of my consulting work, fixed-price quote within 24 hours.

Book a call with Raj →

Get the full Using Service Accounts in Google Apps Script for Server-to-Server Auth script template

I'll email you a production-ready, commented version you can deploy in 10 minutes.

Need help with this? I handle this as part of my Google Apps Script Consulting service.

Workflow automation, script audits, triggers, quotas, and production best practices.

See how it works →