SignetMail docs Open portal →

#Google Workspace

SignetMail works with Google Workspace (Gmail) as an alternative to Microsoft 365. The server reads users and groups from the Google Admin SDK, lets administrators sign in to the portal with their Google account, and sets each user's Gmail signature directly — no add-in and nothing to install on the users' computers.

A server runs against one directory: either Microsoft Entra ID or Google Workspace. Organizations that use both need two separate installations.

#How it works

Function Microsoft 365 Google Workspace
Users and groups Microsoft Graph Admin SDK Directory API
Portal sign-in Entra ID (MSAL) Google Sign-In (ID token)
Getting the signature to the user Outlook add-in, Windows agent, transport rule The server writes the signature into each user's Gmail settings (sendAs)

Everything in the portal — signatures, rules, campaigns, template variables, audit log and the license — works the same way.

The server authenticates with a service account that has domain-wide delegation: it acts as the directory administrator to read the directory, and as each user to update the signature setting in that user's mailbox. No user passwords or consent screens are involved.

#What to know first

  • Gmail applies the signature itself when the user composes; SignetMail only keeps the Gmail setting up to date. Updates appear within minutes.
  • Gmail has no separate signature for replies. SignetMail sets the full signature (the new message variant). Users can choose in Gmail whether the signature appears above or below quoted text.
  • Only the primary address of each user is updated (not aliases or delegated mailboxes).
  • Gmail accepts signatures up to 10,000 characters of HTML and cleans the HTML it receives (for example it removes <style> blocks). Use inline styles, as the built-in templates do.
  • A user can still edit their signature in Gmail. SignetMail overwrites it only when the signature changes, after a server restart, or when you press Overwrite all signatures on the Google Workspace page.
  • Users without an assigned signature (no rule matches) are left untouched; existing signatures are never deleted.

#1. Create the service account

You need a Google Cloud project (any project works; it does not need billing) and permission to create service accounts. A Workspace super admin is required for step 2.

  1. Open Google Cloud console → IAM & Admin → Service accounts → Create service account. Name it signetmail. Skip the optional role and access steps.
  2. In APIs & Services → Library, enable Admin SDK API and Gmail API for the same project.
  3. Open the service account → Keys → Add key → Create new key → JSON. Save the file as service-account.json.
  4. Open the service account Details and copy the numeric Unique ID (also called Client ID). You need it in the next step.

Warning. The JSON key can impersonate users in your domain. Store it only on the SignetMail server, never commit or e-mail it, and delete it from your computer afterwards. If the organization policy Disable service account key creation is active, a Google Cloud organization administrator must allow it for this project.

#2. Authorize domain-wide delegation

In the Google Admin console (as a super admin): Security → Access and data control → API controls → Manage domain-wide delegation → Add new.

  • Client ID: the numeric Unique ID from step 1.
  • OAuth scopes (comma-separated, exactly these four):
https://www.googleapis.com/auth/admin.directory.user.readonly,
https://www.googleapis.com/auth/admin.directory.group.readonly,
https://www.googleapis.com/auth/admin.directory.group.member.readonly,
https://www.googleapis.com/auth/gmail.settings.basic

The first three are read-only. gmail.settings.basic allows changing Gmail settings (it is what writes the signature); it does not allow reading mail.

Note. Changes to delegation can take up to 24 hours to take effect, though they usually apply within minutes.

#3. Create the sign-in client for the portal

  1. In Google Cloud console → APIs & Services → OAuth consent screen, choose Internal (only users of your Workspace) and fill in the application name SignetMail.
  2. Credentials → Create credentials → OAuth client ID → Web application. Under Authorized JavaScript origins add https://<your-host> (for example https://app.example.com). No redirect URI is needed.
  3. Copy the Client ID (…apps.googleusercontent.com). It is public; it is not a secret.

Only accounts of the domains you list in GOOGLE_DOMAIN can sign in, and the e-mail must be verified. Personal Gmail accounts are rejected.

#4. Configure the server

On the server, in the installation folder (see Install the server):

  1. Create the folder google and put the key there as google/service-account.json. The container runs as user ID 1654, so: chmod 750 google && chmod 640 google/service-account.json && sudo chown -R root:1654 google.
  2. Add to .env:
GOOGLE_ADMIN_EMAIL=admin@example.com
GOOGLE_CLIENT_ID=1234567890-abc.apps.googleusercontent.com
GOOGLE_DOMAIN=example.com
PORTAL_OWNER=admin@example.com

GOOGLE_ADMIN_EMAIL is a super admin the service account acts as when reading the directory. PORTAL_OWNER is the Google e-mail of the first Owner. Optionally GOOGLE_PUSH_SIGNATURES=false switches off the automatic push (see below).

  1. Start with the Google override file:
docker compose -f docker-compose.yml -f docker-compose.google.yml up -d

Use the same two -f options for every later docker compose command (or set COMPOSE_FILE=docker-compose.yml:docker-compose.google.yml in .env).

Note. The override file switches off the Microsoft sign-in, so the ENTRA_* values in .env are not used and may stay empty (Compose prints a warning for them).

#5. Verify

  1. Open https://<your-host>/health. After the first directory sync it returns ok.
  2. Open the portal. You should see Sign in with Google; sign in as the Owner.
  3. In Who gets which signature (see First steps) search for a user; the profile fields (title, department, phone) come from the Google directory.
  4. A Google Workspace item appears in the navigation. Press Push signatures now. The page shows how many signatures were updated and the first errors, if any.
  5. In Gmail (a test user): Settings → See all settings → General → Signature. The signature appears there; if Gmail is already open, reload it.

#Automatic push

When GOOGLE_PUSH_SIGNATURES is true (the default in the override file), the server checks all users about once an hour, after the directory sync (SignetMail:Google:PushIntervalMinutes, minimum 5), and sends only signatures that changed. Changes to a user's job title, to a template, or to rules therefore reach Gmail within the hour. Press Push signatures now to apply a change immediately.

Each user who receives a signature counts as an active user for the license.

#Directory fields

Signature variable Google Workspace field
user.displayName, givenName, surname Name (full, first, last)
user.jobTitle, department, companyName Organization → primary entry: Job title, Department, Company
user.officeLocation Organization location, otherwise the user's location (building, area)
user.mobilePhone Phone of type Mobile
user.businessPhone Phone of type Work
user.mail Primary e-mail
user.ext.<schema>_<field> Custom attributes, in lower case, for example schema Staff with field Employee_ID becomes user.ext.staff_employee_id

Suspended and archived accounts do not receive signatures. The directory is re-read every SyncIntervalMinutes (default 60).

#Groups

Rules and campaigns can target Google groups; the group picker lists the groups of your domain and membership includes members of nested groups. Group membership is read only for groups that a rule or campaign uses.

Portal access roles are assigned to individual users (by Google e-mail), not to groups.

#Troubleshooting

Symptom Cause and fix
/health stays starting or degraded Read the server log (docker compose logs signetmail-api). The next rows describe the usual messages.
Google token: unauthorized_client Domain-wide delegation is missing or has the wrong Client ID or scopes. Repeat step 2 and wait a few minutes.
Google token: invalid_grant GOOGLE_ADMIN_EMAIL is not a user in the domain, or the server clock is wrong.
Google API: 403 Not Authorized to access this resource/api The admin e-mail is not a super admin, or the Admin SDK API is not enabled in the project.
Google API: 403 Gmail API has not been used… Enable the Gmail API in the same project as the service account.
One user fails with Gmail mailbox does not exist / Mail service not enabled The user has no Gmail license. Assign a Workspace edition with Gmail or ignore the user.
signature is longer than 10000 characters Simplify the template (fewer images or inline styles).
Sign-in: Google account is not allowed The account is not verified, is a personal Gmail account, or its domain is not GOOGLE_DOMAIN.
Sign-in button does not appear The origin in the OAuth client does not exactly match https://<your-host>, or a browser extension blocks accounts.google.com.
Portal shows no access after sign-in The e-mail is not an Owner or has no role. Check PORTAL_OWNER and Access.
Signature in Gmail shows without styling Gmail removed unsupported HTML. Use inline style attributes and simple tables.

#Security notes

  • The service account key is the most sensitive file of the installation. Rotate it (create a new key, replace the file, restart, delete the old key) at least yearly and whenever someone who had access leaves.
  • Delegation is limited to the four scopes above. Remove the entry in the Admin console to cut off SignetMail immediately.
  • The portal accepts only verified accounts of the listed domains, and the ID token is checked against Google's public keys, the Client ID and the expiry on every request. Sessions last about one hour; after that, sign in again.
  • Restrict the portal to your office addresses with PORTAL_ALLOWED_IPS (see Security).
SignetMail documentation · version main