I’m working on an application that sends emails using Gmail API with a service account that has domain-wide delegation. The service account impersonates a regular user account (let’s call it [email protected]).
The email sending works perfectly, but I’m running into an issue with the sender address. I want the emails to show a custom sender like "Support Team" <[email protected]> in the From field.
When I try to set a custom From header in my MIME message, it gets ignored and the emails still show [email protected] as the sender. I think the API might be overriding my custom From field when it impersonates the user account.
Is there a way to control the From field when using service account impersonation? Maybe there are security restrictions preventing this?
Here’s my current implementation:
import base64
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from googleapiclient.discovery import build
from google.oauth2 import service_account
# Setup credentials with impersonation
credentials = service_account.Credentials.from_service_account_file(
'credentials.json',
scopes=['https://www.googleapis.com/auth/gmail.send']
)
credentials = credentials.with_subject('[email protected]')
gmail_service = build('gmail', 'v1', credentials=credentials)
# Create email message
email_msg = MIMEMultipart('alternative')
email_msg.attach(MIMEText("<p>Hello from support!</p>", 'html'))
email_msg.attach(MIMEText("Hello from support!", 'plain'))
email_msg['Subject'] = 'Support Response'
email_msg['To'] = '[email protected]'
email_msg['From'] = '"Support Team" <[email protected]>' # This gets overridden
# Send the email
raw_message = {'raw': base64.urlsafe_b64encode(email_msg.as_bytes()).decode()}
gmail_service.users().messages().send(userId="me", body=raw_message).execute()
yeah, that’s gmail’s security kicking in - you can’t just throw any from address when impersonating someone. gmail locks the from field to whoever you’re impersonating. only way around it i’ve found is setting up email aliases in the gsuite admin console for that user. then you can use those aliases as your from addresses.
Had this exact problem last year building our notification system. The issue isn’t just aliases or send-as settings - there’s another layer to consider. Even with proper send-as config, I found that service account delegation scope matters a lot. You need to make sure the impersonated user can actually send from that alternative address within your org’s policies. What worked for me was creating a dedicated sending account instead of using [email protected]. I set up [email protected], gave it send-as permissions for [email protected], then had the service account impersonate the notifications account. This felt cleaner security-wise and avoided conflicts with the admin account’s existing email behavior. Also check your domain’s DMARC policy - sometimes the From header works in testing but gets rejected by recipient servers due to auth failures.
This is actually a security feature, not a bug. Gmail’s API won’t let you send emails from addresses that don’t belong to the authenticated user - it prevents spoofing. When you’re impersonating [email protected], Gmail blocks messages from other addresses like [email protected].
Here’s the fix: add [email protected] as a “send-as” address for the admin account. Log into Gmail as [email protected], go to Settings > Accounts and Import > Send mail as, then add [email protected]. Google will send a verification email to confirm you own that address.
Once that’s done, your code should work exactly as-is. Gmail will accept the custom From header because [email protected] is now authorized to send through that account. You get your branded emails without breaking security.