Domain-wide delegation allows a service account to act on behalf of users in a Google Workspace domain without requiring individual OAuth consent flows. For AI agents that need to send emails, schedule meetings, and manage organizational resources, this capability is essential.
This document covers the complete configuration process, the specific scopes required for common operations, and the security considerations involved.
Architecture Overview
The setup involves three components:
- 1.Google Cloud Project - Contains the service account
- 2.Service Account - The identity that makes API calls
- 3.Google Workspace Admin Console - Where delegation is authorized
The service account authenticates using a private key, then impersonates a domain user to access their resources. All actions are logged with both the service account identity and the impersonated user.
Creating the Service Account
Step 1: Google Cloud Console
Navigate to IAM & Admin → Service Accounts in the Google Cloud Console.
Create a new service account: - Name: Descriptive identifier (e.g., "ai-agents-workspace") - ID: Auto-generated, will become the email address - Description: Purpose and scope of access
Step 2: Enable Domain-Wide Delegation
After creation, open the service account details:
- 1.Navigate to the "Details" tab
- 2.Expand "Show domain-wide delegation"
- 3.Check "Enable Google Workspace Domain-wide Delegation"
This generates a Client ID—a numeric identifier required for the admin console configuration.
`
Client ID: 103828366368623534127
`
Step 3: Create and Secure the Key
Under the "Keys" tab: 1. Add Key → Create new key 2. Select JSON format 3. Download immediately—this is the only opportunity
The JSON key file contains the private key material. Security requirements: - Never commit to version control - Store encrypted at rest - Restrict file system permissions - Rotate on a defined schedule
Configuring Domain-Wide Delegation
Accessing the Configuration
In Google Workspace Admin Console: 1. Navigate to Security → Access and data control → API controls 2. Click "Manage Domain Wide Delegation"
Note: Google periodically reorganizes the admin console. If the path changes, search for "domain wide delegation" in the admin console search bar.
Adding the Client
- 1.Click "Add new"
- 2.Enter the Client ID from the service account
- 3.Enter the required OAuth scopes
Scope Format
Scopes must be entered as a comma-separated list without spaces:
`
https://www.googleapis.com/auth/gmail.send,https://www.googleapis.com/auth/calendar.events
`
Required Scopes by Service
Gmail (8 scopes)
`
https://www.googleapis.com/auth/gmail.send
https://www.googleapis.com/auth/gmail.compose
https://www.googleapis.com/auth/gmail.modify
https://www.googleapis.com/auth/gmail.readonly
https://www.googleapis.com/auth/gmail.labels
https://www.googleapis.com/auth/gmail.settings.basic
https://www.googleapis.com/auth/gmail.settings.sharing
https://mail.google.com/
`
Calendar (4 scopes)
`
https://www.googleapis.com/auth/calendar
https://www.googleapis.com/auth/calendar.events
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/calendar.settings.readonly
`
Drive (5 scopes)
`
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/drive.file
https://www.googleapis.com/auth/drive.readonly
https://www.googleapis.com/auth/drive.metadata.readonly
https://www.googleapis.com/auth/drive.appdata
`
Docs, Sheets, Slides (6 scopes)
`
https://www.googleapis.com/auth/documents
https://www.googleapis.com/auth/documents.readonly
https://www.googleapis.com/auth/spreadsheets
https://www.googleapis.com/auth/spreadsheets.readonly
https://www.googleapis.com/auth/presentations
https://www.googleapis.com/auth/presentations.readonly
`
Admin SDK (14 scopes)
`
https://www.googleapis.com/auth/admin.directory.user
https://www.googleapis.com/auth/admin.directory.user.readonly
https://www.googleapis.com/auth/admin.directory.group
https://www.googleapis.com/auth/admin.directory.group.readonly
https://www.googleapis.com/auth/admin.directory.device.chromeos
https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly
https://www.googleapis.com/auth/admin.directory.device.mobile
https://www.googleapis.com/auth/admin.directory.device.mobile.readonly
https://www.googleapis.com/auth/admin.directory.orgunit
https://www.googleapis.com/auth/admin.directory.orgunit.readonly
https://www.googleapis.com/auth/admin.directory.resource.calendar
https://www.googleapis.com/auth/admin.directory.resource.calendar.readonly
https://www.googleapis.com/auth/admin.directory.customer
https://www.googleapis.com/auth/admin.directory.customer.readonly
`
Additional Services (14 scopes)
`
https://www.googleapis.com/auth/adwords
https://www.googleapis.com/auth/adwords.readonly
https://www.googleapis.com/auth/content
https://www.googleapis.com/auth/analytics
https://www.googleapis.com/auth/analytics.readonly
https://www.googleapis.com/auth/webmasters
https://www.googleapis.com/auth/webmasters.readonly
https://www.googleapis.com/auth/business.manage
https://www.googleapis.com/auth/plus.business.manage
https://www.googleapis.com/auth/businesscommunications
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/cloud-platform.read-only
https://www.googleapis.com/auth/contacts
https://www.googleapis.com/auth/contacts.readonly
`
Propagation Delay
Domain-wide delegation changes do not take effect immediately. Propagation can take up to 24 hours.
Recommendation: After configuring or modifying scopes, wait at least one hour before testing. If errors persist, wait until the following day before further troubleshooting.
Implementation
Authentication Pattern
`typescript
import { google } from 'googleapis';
const auth = new google.auth.GoogleAuth({
keyFile: 'credentials/service-account.json',
scopes: ['https://www.googleapis.com/auth/gmail.send'],
clientOptions: {
subject: 'user@domain.com' // User to impersonate
}
});
`
The subject parameter specifies which user the service account will act as. All API calls will appear to come from that user.
Sending Email Example
`typescript
async function sendEmail(
impersonateUser: string,
to: string,
subject: string,
body: string
): Promise
const gmail = google.gmail({ version: 'v1', auth });
const message = [
'Content-Type: text/html; charset=utf-8',
'MIME-Version: 1.0',
To: ${to},
Subject: ${subject},
'',
body
].join('\n');
const encodedMessage = Buffer.from(message)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
await gmail.users.messages.send({
userId: 'me',
requestBody: { raw: encodedMessage }
});
}
`
Calendar Event Example
`typescript
async function createCalendarEvent(
impersonateUser: string,
event: CalendarEventParams
): Promise
const calendar = google.calendar({ version: 'v3', auth });
const response = await calendar.events.insert({
calendarId: 'primary',
requestBody: {
summary: event.title,
start: { dateTime: event.start.toISOString() },
end: { dateTime: event.end.toISOString() },
attendees: event.attendees.map(email => ({ email }))
}
});
return response.data.id;
}
`
Common Issues and Solutions
"Not authorized to access this resource"
Possible causes: - Impersonated user doesn't exist in the domain - Required scope not configured in admin console - Propagation not complete
Resolution: Verify user exists, confirm scope configuration, wait for propagation.
"Delegation denied"
Possible causes: - Domain-wide delegation not enabled on service account - Client ID mismatch between service account and admin console entry
Resolution: Verify delegation checkbox is enabled, confirm Client ID matches exactly.
"Invalid grant"
Possible causes: - Requested scope not in admin console configuration - Clock skew between server and Google
Resolution: Compare requested scopes with configured scopes exactly, verify server time synchronization.
Admin SDK returns 403 for user operations
Admin SDK requires the impersonated user to have admin privileges. Impersonating a regular user will fail for administrative operations even with proper scope configuration.
Security Considerations
Key Management
The service account key provides complete access to all configured capabilities. Key security is critical:
- Store in secure, encrypted storage
- Restrict access to necessary systems only
- Implement key rotation schedule
- Monitor for unauthorized access attempts
Scope Minimization
Configure only the scopes actually required. The comprehensive list above represents maximum capability, not recommended minimum. Evaluate each scope against actual requirements.
Audit Logging
All API calls are logged in Google Workspace audit logs, showing: - Service account identity - Impersonated user - Action performed - Timestamp
Regular audit log review helps identify unauthorized access or misuse.
Impersonation Restrictions
Consider which users can be impersonated: - Limit to specific users or organizational units if possible - Use dedicated service accounts for different purposes - Document authorized impersonation targets
Testing Configuration
Verification script for basic functionality:
`typescript
async function verifyConfiguration(): Promise`
FAQ
Why enable 51 scopes if not all are immediately needed?
Adding scopes later requires re-authorization and propagation delays. Comprehensive initial configuration reduces operational friction for future capability additions. However, this is a trade-off—more scopes mean larger attack surface if credentials are compromised.
Can multiple service accounts have delegation?
Yes. Each service account has its own Client ID and separate admin console entry. This enables separation of concerns—different service accounts for different purposes with different scope sets.
What happens if the impersonated user is suspended or deleted?
API calls will fail. Service account access depends on valid impersonation targets. Monitor user status for accounts used in automation.
Is there a scope limit?
No documented limit exists. The practical limit is the admin console interface's handling of the scope string.
How do I audit what the service account has done?
Google Workspace Admin Console → Reports → Audit → shows all API activity, including service account actions. Filter by actor to see specific service account activity.
Domain-wide delegation provides powerful automation capabilities. The configuration investment is substantial, but the operational benefits—automated email, calendar management, user administration—justify the effort for organizations requiring programmatic Workspace access.
