I’m developing a Workspace app that after being installed for all users using an admin user, allows to impersonate a project service account using the OAuth2 client ID. With that service account impersonation, then I try to query user’s emails using the Gmail API. I’m using the Google Python client to handle all the flow:
Collect the consent token with the OAuth2 client ID
Query all users using the Directory API
Impersonating a service account with a domain-wide delegation
google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials', '{\n "error": {\n "code": 404,\n "message": "Not found; Gaia id not found for email EMAIL",\n "status": "NOT_FOUND"\n }\n}\n')
It’s a bit confusing since there are different meanings for impersonation in this context. From your code, you’re impersonating a service account, not a user. Service accounts aren’t valid gmail users and can’t directly use the gmail API. Instead, you need to impersonate users. A service account is required to impersonate users, so you’re at least part way there
If you can’t download the key and have to impersonate the service account first, then that requires a little extra work. Unfortunately the client libraries don’t handle that flow as easily. In that case, you’ll need to implement the flow yourself. The protocol can be found at https://developers.google.com/identity/protocols/oauth2/service-account#httprest
While that looks long, most of it is about constructing and signing the JWT which you won’t do that way. Use the signJWT method in the IAM API instead. Once you have the signed JWT, follow the steps to exchange it for an access token.
Thanks, @sbazyl ! I followed your suggestion with the service account and it worked like a charm.
I’m going to explore the impersonate first, delegate latter approach for academic purposes. I was exploring that before your answer. I got a dead end with the current client libraries.