You’ve probably encountered this problem if you’ve developed a Google Chat bot: the API sends you a membership event with a User ID (users/1154, for example), but it completely ignores the email field. Regretfully, the email address is typically required by your business logic.
Your Service Account does not have a contact list, thus when you attempt the People API, it returns blank data. You may try the Admin SDK, however since default Service Account calls don’t have user admin rights, they would return 403 Forbidden. You consider Domain-Wide Delegation (DwD), but allowing a bot to pretend to be any user is like trying to shatter a nut with a sledgehammer.
There’s a better approach. Combining the direct assignment of a custom role to a Service Account allows us to
The Strategy
Instead of using Domain-Wide Delegation to let the Service Account impersonate an Admin, we make the Service Account an Admin itself—but strictly a read-only one with a custom role.
Read Users Custom Role Assigned to Service AccountAssign this custom role directly to your Service Account’s email address.
3. Local Development
Use (acting as the service account) to run your scripts locally, rather than Domain-Wide Delegation (the service account acting as a user), keeping your local environment key-free.
The Solution
In a production environment on Google Cloud, your code likely uses Application Default Credentials (ADC) to authenticate as the Service Account. Since the Service Account itself holds the Admin privileges, no special “impersonation” logic is needed in your code—it just works.
However, for local testing, we don’t want to download long-lived JSON keys. Instead, we use Service Account Impersonation to temporarily act as the bot.
Here is a bash script that demonstrates the local testing flow. It uses gcloud to generate a token for the Service Account (using your own credentials to authorize the impersonation) and then queries the Admin SDK Directory API.
When you run this script, you’ll see the impersonation in action. gcloud handles the credential exchange, and the Admin SDK accepts the token because the Service Account itself holds the permissions.
- No Keys: You aren’t downloading long-lived JSON key files to your laptop.
- Audit Trails: The Admin Audit log will show the Service Account performing the read, rather than an impersonated Super Admin.
- Least Privilege: The bot can only read users. It can’t delete accounts, reset passwords, or read Gmail, which are risks often associated with broad Domain-Wide Delegation scopes.