Google Workspace Delegated Access Setup
Tempr's Calendar import and webhook paths use a Google Workspace service account with domain-wide delegation.
This page documents how to create the Google Cloud credential and authorize its delegated access in the Google Admin console.
Use this before running the Google Calendar import service or Google Calendar webhook setup.
What Tempr Needs
Tempr currently authenticates to Google Calendar through:
src/Modules/Calendar/Services/GoogleWorkspaceClientFactory.php
That factory loads service account JSON credentials and impersonates a Workspace user with:
$client->setSubject($subject);
Because of that, Tempr needs:
- a Google Cloud project
- enabled Google Workspace APIs
- a service account with domain-wide delegation
- a service account JSON key available to the app
- the service account's numeric OAuth Client ID authorized in Google Admin
- the smallest required OAuth scopes delegated to that client ID
Do not use a user-consent OAuth web client for this Calendar import path. In Google Admin, the delegated access screen calls the service account identifier a Client ID. That is the numeric OAuth Client ID from the service account's advanced settings.
Required APIs
In the Google Cloud project, enable:
- Google Calendar API
- Admin SDK API
The Admin SDK API is only required for Workspace-wide user discovery, such as:
php artisan calendar:import-google --workspace
Required Delegated Scopes
Authorize these scopes for Tempr Calendar import and webhook sync:
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/calendar.calendarlist.readonly
https://www.googleapis.com/auth/admin.directory.user.readonly
Scope usage:
| Scope | Used for |
|---|---|
calendar.readonly | Reading calendar event data and creating Calendar API event watch channels. |
calendar.calendarlist.readonly | Discovering calendars visible to an impersonated Workspace user. |
admin.directory.user.readonly | Listing active Workspace users for calendar:import-google --workspace. |
If an environment will never run Workspace-wide discovery, the Directory scope can be omitted. Production credentials normally include all three so one credential supports imports, webhooks, and workspace discovery.
Step 1: Create Or Select A Google Cloud Project
Use a dedicated Google Cloud project for Tempr Workspace automation.
Recommended project ownership:
- owned by the organization's Google Cloud organization
- limited editor access
- billing configured if required by the organization
- no unrelated workloads
Step 2: Enable APIs
In Google Cloud Console:
- Open the project.
- Go to
APIs & Services > Library. - Enable
Google Calendar API. - Enable
Admin SDK API.
Step 3: Create The Service Account
In Google Cloud Console:
- Go to
IAM & Admin > Service Accounts. - Click
Create service account. - Use a clear name, such as
tempr-calendar-sync. - Add a description, such as
Tempr Calendar import and webhook sync. - Finish service account creation.
The service account does not need broad project roles for Calendar API access through domain-wide delegation. Keep project-level permissions minimal.
Step 4: Enable Domain-Wide Delegation
Open the service account and enable domain-wide delegation:
- Go to
IAM & Admin > Service Accounts. - Open the service account.
- Find
Advanced settings. - Enable or confirm
Domain-wide delegation. - Copy the service account's numeric
Client ID.
This numeric Client ID is what the Google Admin console authorizes.
The service account email and the service account numeric Client ID are different values. The Admin console wants the numeric Client ID.
Step 5: Create The JSON Key
Create a JSON key for the service account:
- Open the service account.
- Go to
Keys. - Click
Add key. - Choose
Create new key. - Select
JSON. - Download the key.
Store the JSON file in the app's configured secrets/storage location. Do not commit it to git.
Tempr reads the path from:
CALENDAR_GOOGLE_CREDENTIALS_JSON=/absolute/path/to/google-service-token.json
Step 6: Authorize The Client In Google Admin
This step must be completed by a Google Workspace super administrator.
In Google Admin Console:
- Go to
Security > Access and data control > API controls. - Open
Manage Domain Wide Delegation. - Click
Add new. - Paste the service account's numeric Client ID into
Client ID. - Paste the required OAuth scopes into
OAuth scopes. - Click
Authorize.
Use a comma-delimited scope list:
https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/calendar.calendarlist.readonly,https://www.googleapis.com/auth/admin.directory.user.readonly
Step 7: Configure Tempr
Set or confirm:
CALENDAR_GOOGLE_CREDENTIALS_JSON=/absolute/path/to/google-service-token.json
CALENDAR_GOOGLE_DEFAULT_USER=admin-or-calendar-user@example.com
CALENDAR_GOOGLE_WORKSPACE_CUSTOMER=my_customer
CALENDAR_GOOGLE_PAGE_SIZE=100
CALENDAR_IMPORT_QUEUE=default
For webhooks, also set:
CALENDAR_GOOGLE_WEBHOOK_URL=https://your-public-host.example.com/integrations/google/calendar/webhooks/callback
CALENDAR_GOOGLE_WEBHOOK_TTL_SECONDS=604800
CALENDAR_GOOGLE_WEBHOOK_RENEWAL_THRESHOLD=86400
Clear cached config:
php artisan optimize:clear
Step 8: Smoke Test Access
Test one known user:
php artisan calendar:import-google --user=scheduler@example.com --dry-run
If Workspace discovery is enabled, test a small user limit:
php artisan calendar:import-google --workspace --max-users=1 --dry-run
Then run a real import:
php artisan calendar:import-google --user=scheduler@example.com --sync
After sources exist, create webhook channels:
php artisan calendar:google-webhooks:sync
Troubleshooting
Invalid Grant Or Unauthorized Client
Common causes:
- Domain-wide delegation is not enabled on the service account.
- The Admin console authorized the service account email instead of the numeric Client ID.
- The subject user does not exist in the Workspace domain.
- The service account JSON belongs to a different service account than the Admin console entry.
Insufficient Permission
Check the delegated scopes in Google Admin.
The Calendar import path needs:
https://www.googleapis.com/auth/calendar.readonly
https://www.googleapis.com/auth/calendar.calendarlist.readonly
Workspace discovery needs:
https://www.googleapis.com/auth/admin.directory.user.readonly
Workspace Import Finds No Users
Check:
Admin SDK APIis enabled.CALENDAR_GOOGLE_WORKSPACE_CUSTOMERis correct.admin.directory.user.readonlyis authorized.CALENDAR_GOOGLE_DEFAULT_USERcan impersonate a Workspace user in the domain.
Calendar Import Finds No Calendars
Check:
Google Calendar APIis enabled.calendar.calendarlist.readonlyis authorized.- The impersonated user has access to the calendar.
- The target calendar is not hidden, or run with
--include-hidden.
Security Notes
- Grant only the scopes Tempr needs.
- Keep the service account in a dedicated Google Cloud project.
- Restrict who can edit the project and service account.
- Rotate JSON keys if they are exposed.
- Remove old Admin console domain-wide delegation entries when credentials are retired.
- Review delegated clients regularly in Google Admin.