In python, I'm trying to call the GMail API via a service account with Delegated domain-wide authority, without using SERVICE_ACCOUNT_FILE
.
My objective is to avoid creating a secret Key
for the service account. Instead, I gave the Service Account Token Creator
role to the process owner (me in local dev, App Engine Service Account in prod).
In the code below I successfully get and use an access token for the service account, without any SERVICE_ACCOUNT_FILE
.
from google.cloud.iam_credentials_v1 import IAMCredentialsClient
from google.oauth2.credentials import Credentials
import googleapiclient.discovery
tk = IAMCredentialsClient().generate_access_token(
name=f'projects/-/serviceAccounts/{service_id}',
scope=['https://www.googleapis.com/auth/gmail.insert'],
# subject='admin@my.domain' doesn't work here :'(
)
service = googleapiclient.discovery.build('gmail', 'v1', credentials=Credentials(tk.access_token))
response = service.users().messages().insert(userId='user@my.domain', body=body).execute()
Problem is, after granting permissions to the service account in Google Admin of my.domain
, I get the following error:
{'message': 'Precondition check failed.', 'domain': 'global', 'reason': 'failedPrecondition'}
I suspect that what I am missing is the subject
, i.e. the email of an admin at my.domain
.
I know I can provide the subject
by constructing the credentials
differently:
from google.oauth2 import service_account
credentials = service_account.Credentials.from_service_account_file(key_file, scopes=scopes)
delegated_credentials = credentials.with_subject('admin@my.domain'). # <- I need this
service = googleapiclient.discovery.build('gmail', 'v1', credentials=delegated_credentials)
But this requires the creation of a secret key, which I'd like to avoid.
Is there a way to pass the subject in the first code example above ?